diff --git a/Help/release/dev/short-object-names.rst b/Help/release/dev/short-object-names.rst new file mode 100644 index 0000000000..1ae306d190 --- /dev/null +++ b/Help/release/dev/short-object-names.rst @@ -0,0 +1,7 @@ +short-object-names +------------------ + +* There is now the :variable:`CMAKE_INTERMEDIATE_DIR_STRATEGY` variable (and + associated environment variable :envvar:`CMAKE_INTERMEDIATE_DIR_STRATEGY`) + that may be used to change the strategy used to name intermediate + directories used for object files (and other associated target metadata). diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 41352d9570..4ea0d556e9 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1440,6 +1440,20 @@ bool cmGlobalGenerator::Compute() return false; } + if (cmValue v = this->CMakeInstance->GetCacheDefinition( + "CMAKE_INTERMEDIATE_DIR_STRATEGY")) { + if (*v == "FULL") { + this->IntDirStrategy = IntermediateDirStrategy::Full; + } else if (*v == "SHORT") { + this->IntDirStrategy = IntermediateDirStrategy::Short; + } else { + this->GetCMakeInstance()->IssueMessage( + MessageType::FATAL_ERROR, + cmStrCat("Unsupported intermediate directory strategy '", *v, '\'')); + return false; + } + } + // Some generators track files replaced during the Generate. // Start with an empty vector: this->FilesReplacedDuringGenerate.clear(); @@ -1981,6 +1995,17 @@ void cmGlobalGenerator::ClearGeneratorMembers() this->WarnedExperimental.clear(); } +bool cmGlobalGenerator::SupportsShortObjectNames() const +{ + return false; +} + +bool cmGlobalGenerator::UseShortObjectNames() const +{ + return this->SupportsShortObjectNames() && + this->IntDirStrategy == IntermediateDirStrategy::Short; +} + void cmGlobalGenerator::ComputeTargetObjectDirectory( cmGeneratorTarget* /*unused*/) const { diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index daaf2aa700..6b6fbbfab7 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -629,6 +629,9 @@ public: std::string const& filename) const; void AddCMP0068WarnTarget(std::string const& target); + virtual bool SupportsShortObjectNames() const; + bool UseShortObjectNames() const; + virtual void ComputeTargetObjectDirectory(cmGeneratorTarget* gt) const; bool GenerateCPackPropertiesFile(); @@ -941,6 +944,13 @@ private: PerConfigModuleDatabases PerConfigModuleDbs; PerLanguageModuleDatabases PerLanguageModuleDbs; + enum class IntermediateDirStrategy + { + Full, + Short, + }; + IntermediateDirStrategy IntDirStrategy = IntermediateDirStrategy::Full; + protected: float FirstTimeProgress; bool NeedSymbolicMark; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 48974407ed..c96e500dee 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -4287,6 +4287,11 @@ std::string cmLocalGenerator::GetObjectFileNameWithoutTarget( return this->CreateSafeUniqueObjectFileName(objectName, dir_max); } +bool cmLocalGenerator::UseShortObjectNames() const +{ + return this->GlobalGenerator->UseShortObjectNames(); +} + std::string cmLocalGenerator::GetObjectOutputRoot() const { return cmStrCat(this->GetCurrentBinaryDirectory(), "/CMakeFiles"); diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 0eaa6b7154..d9466452b8 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -438,6 +438,7 @@ public: std::string const& GetCurrentBinaryDirectory() const; std::string const& GetCurrentSourceDirectory() const; + bool UseShortObjectNames() const; virtual std::string GetObjectOutputRoot() const; virtual bool AlwaysUsesCMFPaths() const; diff --git a/Source/cmake.cxx b/Source/cmake.cxx index a1cce112d4..a9041ba34a 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2607,7 +2607,7 @@ int cmake::ActualConfigure() this->IntermediateDirStrategy) { this->AddCacheEntry( "CMAKE_INTERMEDIATE_DIR_STRATEGY", *this->IntermediateDirStrategy, - "Select the intermediate directory strategy", cmStateEnums::STRING); + "Select the intermediate directory strategy", cmStateEnums::INTERNAL); } if (!this->State->GetInitializedCacheValue("CMAKE_TEST_LAUNCHER")) { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 71cdbe0d44..7aeb1926f4 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -794,6 +794,7 @@ add_RunCMake_test(CMP0004) add_RunCMake_test(TargetPolicies) add_RunCMake_test(alias_targets) add_RunCMake_test(InterfaceLibrary) +add_RunCMake_test(IntermediateDirStrategy) add_RunCMake_test(no_install_prefix) add_RunCMake_test(configure_file) if(CTestTestTimeout_TIME) diff --git a/Tests/RunCMake/IntermediateDirStrategy/CMakeLists.txt b/Tests/RunCMake/IntermediateDirStrategy/CMakeLists.txt new file mode 100644 index 0000000000..5d1e2985e2 --- /dev/null +++ b/Tests/RunCMake/IntermediateDirStrategy/CMakeLists.txt @@ -0,0 +1,2 @@ +cmake_minimum_required(VERSION 3.10) +project(${RunCMake_TEST} NONE) diff --git a/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyCacheINVALID-result.txt b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyCacheINVALID-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyCacheINVALID-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyCacheINVALID-stderr.txt b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyCacheINVALID-stderr.txt new file mode 100644 index 0000000000..86a1e614ea --- /dev/null +++ b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyCacheINVALID-stderr.txt @@ -0,0 +1,5 @@ +CMake Error: + Unsupported intermediate directory strategy 'INVALID' + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyEnvINVALID-result.txt b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyEnvINVALID-result.txt new file mode 100644 index 0000000000..d00491fd7e --- /dev/null +++ b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyEnvINVALID-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyEnvINVALID-stderr.txt b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyEnvINVALID-stderr.txt new file mode 100644 index 0000000000..86a1e614ea --- /dev/null +++ b/Tests/RunCMake/IntermediateDirStrategy/IntDirStrategyEnvINVALID-stderr.txt @@ -0,0 +1,5 @@ +CMake Error: + Unsupported intermediate directory strategy 'INVALID' + + +CMake Generate step failed. Build files cannot be regenerated correctly. diff --git a/Tests/RunCMake/IntermediateDirStrategy/RunCMakeTest.cmake b/Tests/RunCMake/IntermediateDirStrategy/RunCMakeTest.cmake new file mode 100644 index 0000000000..3bc67872e8 --- /dev/null +++ b/Tests/RunCMake/IntermediateDirStrategy/RunCMakeTest.cmake @@ -0,0 +1,20 @@ +include(RunCMake) + +function(run_cmake_intdir_strategy base strategy) + unset(ENV{CMAKE_INTERMEDIATE_DIR_STRATEGY}) + + if (base STREQUAL "IntDirStrategyCache") + set(RunCMake_TEST_OPTIONS -DCMAKE_INTERMEDIATE_DIR_STRATEGY=${strategy}) + elseif (base STREQUAL "IntDirStrategyEnv") + set(ENV{CMAKE_INTERMEDIATE_DIR_STRATEGY} "${strategy}") + else () + message(FATAL_ERROR "unsupported base: ${base}") + endif () + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${base}${strategy}-build) + run_cmake(${base}${strategy}) +endfunction() + +foreach (strategy IN ITEMS INVALID FULL SHORT) + run_cmake_intdir_strategy(IntDirStrategyCache ${strategy}) + run_cmake_intdir_strategy(IntDirStrategyEnv ${strategy}) +endforeach ()