summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Source/cmDocumentVariables.cxx18
-rw-r--r--Source/cmLocalGenerator.cxx52
-rw-r--r--Source/cmLocalGenerator.h1
-rw-r--r--Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt7
4 files changed, 66 insertions, 12 deletions
diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx
index cf228f1c08..25ef0b2ab1 100644
--- a/Source/cmDocumentVariables.cxx
+++ b/Source/cmDocumentVariables.cxx
@@ -736,6 +736,24 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
"Set to true when the host system is Windows and on cygwin.",false,
"Variables That Describe the System");
+ cm->DefineProperty
+ ("CMAKE_OBJECT_PATH_MAX", cmProperty::VARIABLE,
+ "Maximum object file full-path length allowed by native build tools.",
+ "CMake computes for every source file an object file name that is "
+ "unique to the source file and deterministic with respect to the "
+ "full path to the source file. "
+ "This allows multiple source files in a target to share the same name "
+ "if they lie in different directories without rebuilding when one is "
+ "added or removed. "
+ "However, it can produce long full paths in a few cases, so CMake "
+ "shortens the path using a hashing scheme when the full path to an "
+ "object file exceeds a limit. "
+ "CMake has a built-in limit for each platform that is sufficient for "
+ "common tools, but some native tools may have a lower limit. "
+ "This variable may be set to specify the limit explicitly. "
+ "The value must be an integer no less than 128.",false,
+ "Variables That Describe the System");
+
// Variables that affect the building of object files and
// targets.
//
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 4bf183943a..52322ff012 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -101,6 +101,43 @@ void cmLocalGenerator::Configure()
// relative paths.
this->UseRelativePaths = this->Makefile->IsOn("CMAKE_USE_RELATIVE_PATHS");
+ // Choose a maximum object file name length.
+ {
+#if defined(_WIN32) || defined(__CYGWIN__)
+ this->ObjectPathMax = 250;
+#else
+ this->ObjectPathMax = 1000;
+#endif
+ const char* plen = this->Makefile->GetDefinition("CMAKE_OBJECT_PATH_MAX");
+ if(plen && *plen)
+ {
+ unsigned int pmax;
+ if(sscanf(plen, "%u", &pmax) == 1)
+ {
+ if(pmax >= 128)
+ {
+ this->ObjectPathMax = pmax;
+ }
+ else
+ {
+ cmOStringStream w;
+ w << "CMAKE_OBJECT_PATH_MAX is set to " << pmax
+ << ", which is less than the minimum of 128. "
+ << "The value will be ignored.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ }
+ else
+ {
+ cmOStringStream w;
+ w << "CMAKE_OBJECT_PATH_MAX is set to \"" << plen
+ << "\", which fails to parse as a positive integer. "
+ << "The value will be ignored.";
+ this->Makefile->IssueMessage(cmake::AUTHOR_WARNING, w.str());
+ }
+ }
+ }
+
this->Configured = true;
this->GetGlobalGenerator()->SetCurrentLocalGenerator(previousLg);
@@ -2314,16 +2351,11 @@ cmLocalGeneratorShortenObjectName(std::string& objName,
}
}
-static bool cmLocalGeneratorCheckObjectName(std::string& objName,
- std::string::size_type dir_len)
+static
+bool cmLocalGeneratorCheckObjectName(std::string& objName,
+ std::string::size_type dir_len,
+ std::string::size_type max_total_len)
{
- // Choose a maximum file name length.
-#if defined(_WIN32) || defined(__CYGWIN__)
- std::string::size_type const max_total_len = 250;
-#else
- std::string::size_type const max_total_len = 1000;
-#endif
-
// Enforce the maximum file name length if possible.
std::string::size_type max_obj_len = max_total_len;
if(dir_len < max_total_len)
@@ -2414,7 +2446,7 @@ cmLocalGenerator
}
#if defined(CM_LG_ENCODE_OBJECT_NAMES)
- cmLocalGeneratorCheckObjectName(ssin, dir_len);
+ cmLocalGeneratorCheckObjectName(ssin, dir_len, this->ObjectPathMax);
#else
(void)dir_len;
#endif
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 6b3b7ea638..1be0aa47b8 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -348,6 +348,7 @@ protected:
std::vector<cmLocalGenerator*> Children;
std::map<cmStdString, cmStdString> LanguageToIncludeFlags;
std::map<cmStdString, cmStdString> UniqueObjectNamesMap;
+ std::string::size_type ObjectPathMax;
bool WindowsShell;
bool WindowsVSIDE;
bool WatcomWMake;
diff --git a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
index 57c429e53f..9f7b868735 100644
--- a/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
+++ b/Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt
@@ -10,8 +10,11 @@ IF ("${PROJECT_SOURCE_DIR}" STREQUAL "${ANOTHER_PROJ_SOURCE_DIR}")
GET_FILENAME_COMPONENT(DEEPDIR
${OutOfSource_BINARY_DIR}/../OutOfSourceDeep/deeper ABSOLUTE)
- # The maximum allowed path length on Windows is near this value.
- SET(MAXPATH "250")
+ # Test giving the generator a custom limit.
+ SET(CMAKE_OBJECT_PATH_MAX 220)
+
+ # Use a separate variable for computation.
+ SET(MAXPATH "${CMAKE_OBJECT_PATH_MAX}")
# VS8 adds "OutOfSource/SubDir/OutOfSourceSubdir/../../../" to the
# path of the source file for no good reason. Reduce the length