Quellcode durchsuchen

Merge topic 'pch-instantiate-templates'

8c8f03422e PCH: Template instantiation support

Acked-by: Kitware Robot <[email protected]>
Acked-by: Raul Tambre <[email protected]>
Acked-by: Cristian Adam <[email protected]>
Tested-by: Raul Tambre <[email protected]>
Merge-request: !5168
Brad King vor 5 Jahren
Ursprung
Commit
48ed3bae58

+ 1 - 0
Help/manual/cmake-properties.7.rst

@@ -315,6 +315,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

+ 1 - 0
Help/manual/cmake-variables.7.rst

@@ -444,6 +444,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

+ 13 - 0
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``.

+ 7 - 0
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.

+ 7 - 0
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.

+ 3 - 0
Modules/Compiler/Clang.cmake

@@ -106,6 +106,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> -x ${__pch_header_${lang}})
   endmacro()

+ 10 - 0
Source/cmGeneratorTarget.cxx

@@ -4134,6 +4134,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");
 

+ 1 - 0
Source/cmTarget.cxx

@@ -381,6 +381,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()) {

+ 3 - 1
Tests/RunCMake/CMakeLists.txt

@@ -740,7 +740,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)

+ 17 - 0
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()

+ 16 - 0
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)

+ 5 - 0
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()