diff options
-rw-r--r-- | Source/cmDocumentVariables.cxx | 18 | ||||
-rw-r--r-- | Source/cmLocalGenerator.cxx | 52 | ||||
-rw-r--r-- | Source/cmLocalGenerator.h | 1 | ||||
-rw-r--r-- | Tests/OutOfSource/OutOfSourceSubdir/CMakeLists.txt | 7 |
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 |