diff options
author | Tobias Hieta <tobias@plex.tv> | 2020-08-28 07:16:04 (GMT) |
---|---|---|
committer | Tobias Hieta <tobias@plex.tv> | 2020-09-02 06:30:55 (GMT) |
commit | 8c8f03422e3197a3414a8ed1413fcb9576df0f4b (patch) | |
tree | 526e5b6341f3f63dd848623be82448fab17f5285 | |
parent | 8c833ff0e17e63d9cbf17622abcb70a5fab240b8 (diff) | |
download | CMake-8c8f03422e3197a3414a8ed1413fcb9576df0f4b.zip CMake-8c8f03422e3197a3414a8ed1413fcb9576df0f4b.tar.gz CMake-8c8f03422e3197a3414a8ed1413fcb9576df0f4b.tar.bz2 |
PCH: Template instantiation support
Adds PCH_INSTANTIATE_TEMPLATES target property for enabling template
instantiation in precompiled headers.
Enabled by default. Currently only supported for Clang 11 and newer.
Implements #21133.
-rw-r--r-- | Help/manual/cmake-properties.7.rst | 1 | ||||
-rw-r--r-- | Help/manual/cmake-variables.7.rst | 1 | ||||
-rw-r--r-- | Help/prop_tgt/PCH_INSTANTIATE_TEMPLATES.rst | 13 | ||||
-rw-r--r-- | Help/release/dev/PCH_INSTANTIATE_TEMPLATES.rst | 7 | ||||
-rw-r--r-- | Help/variable/CMAKE_PCH_INSTANTIATE_TEMPLATES.rst | 7 | ||||
-rw-r--r-- | Modules/Compiler/Clang.cmake | 3 | ||||
-rw-r--r-- | Source/cmGeneratorTarget.cxx | 10 | ||||
-rw-r--r-- | Source/cmTarget.cxx | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CMakeLists.txt | 4 | ||||
-rw-r--r-- | Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates-check.cmake | 17 | ||||
-rw-r--r-- | Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates.cmake | 16 | ||||
-rw-r--r-- | Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake | 5 |
12 files changed, 84 insertions, 1 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst index afdf78c..b2e3995 100644 --- a/Help/manual/cmake-properties.7.rst +++ b/Help/manual/cmake-properties.7.rst @@ -313,6 +313,7 @@ Properties on Targets /prop_tgt/OUTPUT_NAME_CONFIG /prop_tgt/OUTPUT_NAME /prop_tgt/PCH_WARN_INVALID + /prop_tgt/PCH_INSTANTIATE_TEMPLATES /prop_tgt/PDB_NAME_CONFIG /prop_tgt/PDB_NAME /prop_tgt/PDB_OUTPUT_DIRECTORY_CONFIG diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst index 53cdd0b..baf4a55 100644 --- a/Help/manual/cmake-variables.7.rst +++ b/Help/manual/cmake-variables.7.rst @@ -443,6 +443,7 @@ Variables that Control the Build /variable/CMAKE_OSX_DEPLOYMENT_TARGET /variable/CMAKE_OSX_SYSROOT /variable/CMAKE_PCH_WARN_INVALID + /variable/CMAKE_PCH_INSTANTIATE_TEMPLATES /variable/CMAKE_PDB_OUTPUT_DIRECTORY /variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG /variable/CMAKE_POSITION_INDEPENDENT_CODE diff --git a/Help/prop_tgt/PCH_INSTANTIATE_TEMPLATES.rst b/Help/prop_tgt/PCH_INSTANTIATE_TEMPLATES.rst new file mode 100644 index 0000000..7c1af2a --- /dev/null +++ b/Help/prop_tgt/PCH_INSTANTIATE_TEMPLATES.rst @@ -0,0 +1,13 @@ +PCH_INSTANTIATE_TEMPLATES +------------------------- + +.. versionadded:: 3.19 + +When this property is set to true, the precompiled header compiler options +will contain a flag to instantiate templates during the generation of the PCH +if supported. This can significantly improve compile times. Supported in Clang +since version 11. + +This property is initialized by the value of the +:variable:`CMAKE_PCH_INSTANTIATE_TEMPLATES` variable if it is set when a target +is created. If that variable is not set, the property defaults to ``ON``. diff --git a/Help/release/dev/PCH_INSTANTIATE_TEMPLATES.rst b/Help/release/dev/PCH_INSTANTIATE_TEMPLATES.rst new file mode 100644 index 0000000..0334204 --- /dev/null +++ b/Help/release/dev/PCH_INSTANTIATE_TEMPLATES.rst @@ -0,0 +1,7 @@ +PCH_INSTANTIATE_TEMPLATES +------------------------- + +* The :prop_tgt:`PCH_INSTANTIATE_TEMPLATES` target property was added to enable + template instantiation in the precompiled header. This is enabled by default + and offers a roughly 20% compile time improvement. Currently only supported + by Clang 11. diff --git a/Help/variable/CMAKE_PCH_INSTANTIATE_TEMPLATES.rst b/Help/variable/CMAKE_PCH_INSTANTIATE_TEMPLATES.rst new file mode 100644 index 0000000..9867f17 --- /dev/null +++ b/Help/variable/CMAKE_PCH_INSTANTIATE_TEMPLATES.rst @@ -0,0 +1,7 @@ +CMAKE_PCH_INSTANTIATE_TEMPLATES +------------------------------- + +.. versionadded:: 3.19 + +This variable is used to initialize the :prop_tgt:`PCH_INSTANTIATE_TEMPLATES` +property of targets when they are created. diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake index 52d5350..6f0e9b3 100644 --- a/Modules/Compiler/Clang.cmake +++ b/Modules/Compiler/Clang.cmake @@ -101,6 +101,9 @@ else() if (NOT CMAKE_GENERATOR MATCHES "Xcode") set(CMAKE_PCH_PROLOGUE "#pragma clang system_header") endif() + if(CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0.0 AND NOT __is_apple_clang) + set(CMAKE_${lang}_COMPILE_OPTIONS_INSTANTIATE_TEMPLATES_PCH -fpch-instantiate-templates) + endif() set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Xclang -include-pch -Xclang <PCH_FILE> -Xclang -include -Xclang <PCH_HEADER>) set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Xclang -emit-pch -Xclang -include -Xclang <PCH_HEADER>) endmacro() diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx index 7c526a0..de981c1 100644 --- a/Source/cmGeneratorTarget.cxx +++ b/Source/cmGeneratorTarget.cxx @@ -4078,6 +4078,16 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions( cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH")); } + if (this->GetPropertyAsBool("PCH_INSTANTIATE_TEMPLATES")) { + std::string varName = cmStrCat( + "CMAKE_", language, "_COMPILE_OPTIONS_INSTANTIATE_TEMPLATES_PCH"); + std::string instantiateOption = + this->Makefile->GetSafeDefinition(varName); + if (!instantiateOption.empty()) { + createOptionList = cmStrCat(createOptionList, ";", instantiateOption); + } + } + const std::string createOptVar = cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH"); diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index bea9001..6aa23c2 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -377,6 +377,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type, initPropValue("UNITY_BUILD_BATCH_SIZE", "8"); initPropValue("UNITY_BUILD_MODE", "BATCH"); initPropValue("PCH_WARN_INVALID", "ON"); + initPropValue("PCH_INSTANTIATE_TEMPLATES", "ON"); #ifdef __APPLE__ if (this->GetGlobalGenerator()->IsXcode()) { diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 65e8b0b..88d0004 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -731,7 +731,9 @@ endif() add_RunCMake_test("CTestCommandExpandLists") -add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}) +add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID} + -DCMAKE_C_COMPILER_VERSION=${CMAKE_C_COMPILER_VERSION}) + add_RunCMake_test("UnityBuild") if(WIN32) diff --git a/Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates-check.cmake b/Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates-check.cmake new file mode 100644 index 0000000..648d387 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates-check.cmake @@ -0,0 +1,17 @@ +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json empty_dir_commands + REGEX "command.*-fpch-instantiate-templates.*empty.dir/cmake_pch.h") +file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json foo_dir_commands + REGEX "command.*-fpch-instantiate-templates.*foo.dir/cmake_pch.h") + +list(LENGTH empty_dir_commands empty_dir_commands_size) +list(LENGTH foo_dir_commands foo_dir_commands_size) + +if (empty_dir_commands_size EQUAL 0) + set(RunCMake_TEST_FAILED "empty target should have -fpch-instantiate-templates compile option present") + return() +endif() + +if (foo_dir_commands_size GREATER 0) + set(RunCMake_TEST_FAILED "foo target should not have -fpch-instantiate-templates compile option present") + return() +endif() diff --git a/Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates.cmake b/Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates.cmake new file mode 100644 index 0000000..3aebbe0 --- /dev/null +++ b/Tests/RunCMake/PrecompileHeaders/PchInstantiateTemplates.cmake @@ -0,0 +1,16 @@ +enable_language(C) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +add_library(empty empty.c) +target_precompile_headers(empty PUBLIC + <stdio.h> + <string.h> +) + +add_library(foo foo.c) +target_precompile_headers(foo PUBLIC + <stdio.h> + <string.h> +) +set_target_properties(foo PROPERTIES PCH_INSTANTIATE_TEMPLATES OFF) diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake index 381b800..74670ba 100644 --- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake +++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake @@ -20,4 +20,9 @@ run_test(PchReuseFromSubdir) run_cmake(PchMultilanguage) if(RunCMake_GENERATOR MATCHES "Make|Ninja") run_cmake(PchWarnInvalid) + + if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND + CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11.0.0) + run_cmake(PchInstantiateTemplates) + endif() endif() |