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.
This commit is contained in:
Tobias Hieta
2020-08-28 09:16:04 +02:00
parent 8c833ff0e1
commit 8c8f03422e
12 changed files with 84 additions and 1 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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``.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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()

View File

@@ -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");

View File

@@ -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()) {

View File

@@ -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)

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()