Explorar el Código

PCH: add an option to disable `-Winvalid-pch`

Fixes: #20295
Cristian Adam hace 5 años
padre
commit
2ce08e5489

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

@@ -127,6 +127,7 @@ Properties on Targets
    /prop_tgt/ARCHIVE_OUTPUT_DIRECTORY
    /prop_tgt/ARCHIVE_OUTPUT_NAME_CONFIG
    /prop_tgt/ARCHIVE_OUTPUT_NAME
+   /prop_tgt/PCH_WARN_INVALID
    /prop_tgt/AUTOGEN_BUILD_DIR
    /prop_tgt/AUTOGEN_ORIGIN_DEPENDS
    /prop_tgt/AUTOGEN_PARALLEL

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

@@ -438,6 +438,7 @@ Variables that Control the Build
    /variable/CMAKE_OSX_ARCHITECTURES
    /variable/CMAKE_OSX_DEPLOYMENT_TARGET
    /variable/CMAKE_OSX_SYSROOT
+   /variable/CMAKE_PCH_WARN_INVALID
    /variable/CMAKE_PDB_OUTPUT_DIRECTORY
    /variable/CMAKE_PDB_OUTPUT_DIRECTORY_CONFIG
    /variable/CMAKE_POSITION_INDEPENDENT_CODE

+ 8 - 0
Help/prop_tgt/PCH_WARN_INVALID.rst

@@ -0,0 +1,8 @@
+PCH_WARN_INVALID
+----------------
+
+When this property is set to true, the precompile header compiler options
+will contain a compiler flag wich should warn about invalid precompiled
+headers e.g. ``-Winvalid-pch`` for GNU compiler.
+
+The defalut value is ``ON``.

+ 6 - 0
Help/release/dev/pch-warn-invalid.rst

@@ -0,0 +1,6 @@
+pch-warn-invalid
+----------------
+
+* The :variable:`CMAKE_PCH_WARN_INVALID` variable was added to initialize the
+  :prop_tgt:`PCH_WARN_INVALID` target property to allow the removal of the
+  precompiled header invalid warning.

+ 5 - 0
Help/variable/CMAKE_PCH_WARN_INVALID.rst

@@ -0,0 +1,5 @@
+CMAKE_PCH_WARN_INVALID
+----------------------
+
+This variable is used to initialize the :prop_tgt:`PCH_WARN_INVALID`
+property of targets when they are created.

+ 3 - 2
Modules/Compiler/GNU.cmake

@@ -114,6 +114,7 @@ macro(__compiler_gnu lang)
   if (NOT CMAKE_GENERATOR MATCHES "Xcode")
     set(CMAKE_PCH_PROLOGUE "#pragma GCC system_header")
   endif()
-  set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -include <PCH_HEADER>)
-  set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -x ${__pch_header_${lang}} -include <PCH_HEADER>)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -include <PCH_HEADER>)
+  set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -x ${__pch_header_${lang}} -include <PCH_HEADER>)
 endmacro()

+ 3 - 2
Modules/Compiler/Intel.cmake

@@ -37,7 +37,8 @@ else()
     set(CMAKE_PCH_EXTENSION .pchi)
     set(CMAKE_LINK_PCH ON)
     set(CMAKE_PCH_EPILOGUE "#pragma hdrstop")
-    set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Winvalid-pch -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
-    set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Winvalid-pch -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_USE_PCH -Wno-pch-messages -pch-use <PCH_FILE> -include <PCH_HEADER>)
+    set(CMAKE_${lang}_COMPILE_OPTIONS_CREATE_PCH -Wno-pch-messages -pch-create <PCH_FILE> -include <PCH_HEADER>)
   endmacro()
 endif()

+ 16 - 2
Source/cmGeneratorTarget.cxx

@@ -3781,9 +3781,16 @@ std::string cmGeneratorTarget::GetPchCreateCompileOptions(
   if (inserted.second) {
     std::string& createOptionList = inserted.first->second;
 
+    if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+      createOptionList = this->Makefile->GetSafeDefinition(
+        cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+    }
+
     const std::string createOptVar =
       cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_CREATE_PCH");
-    createOptionList = this->Makefile->GetSafeDefinition(createOptVar);
+
+    createOptionList = cmStrCat(
+      createOptionList, ";", this->Makefile->GetSafeDefinition(createOptVar));
 
     const std::string pchHeader = this->GetPchHeader(config, language);
     const std::string pchFile = this->GetPchFile(config, language);
@@ -3802,9 +3809,16 @@ std::string cmGeneratorTarget::GetPchUseCompileOptions(
   if (inserted.second) {
     std::string& useOptionList = inserted.first->second;
 
+    if (this->GetPropertyAsBool("PCH_WARN_INVALID")) {
+      useOptionList = this->Makefile->GetSafeDefinition(
+        cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_INVALID_PCH"));
+    }
+
     const std::string useOptVar =
       cmStrCat("CMAKE_", language, "_COMPILE_OPTIONS_USE_PCH");
-    useOptionList = this->Makefile->GetSafeDefinition(useOptVar);
+
+    useOptionList = cmStrCat(useOptionList, ";",
+                             this->Makefile->GetSafeDefinition(useOptVar));
 
     const std::string pchHeader = this->GetPchHeader(config, language);
     const std::string pchFile = this->GetPchFile(config, language);

+ 1 - 0
Source/cmTarget.cxx

@@ -368,6 +368,7 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
     initProp("DISABLE_PRECOMPILE_HEADERS");
     initProp("UNITY_BUILD");
     initPropValue("UNITY_BUILD_BATCH_SIZE", "8");
+    initPropValue("PCH_WARN_INVALID", "ON");
 #ifdef __APPLE__
     if (this->GetGlobalGenerator()->IsXcode()) {
       initProp("XCODE_SCHEME_ADDRESS_SANITIZER");

+ 1 - 1
Tests/RunCMake/CMakeLists.txt

@@ -665,7 +665,7 @@ endif()
 
 add_RunCMake_test("CTestCommandExpandLists")
 
-add_RunCMake_test(PrecompileHeaders)
+add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
 add_RunCMake_test("UnityBuild")
 
 add_RunCMake_test(cmake_command)

+ 22 - 0
Tests/RunCMake/PrecompileHeaders/PchWarnInvalid-check.cmake

@@ -0,0 +1,22 @@
+if (NOT CMAKE_C_COMPILER_ID MATCHES "GNU|Intel" OR
+   (CMAKE_C_COMPILER_ID STREQUAL "Intel" AND CMAKE_HOST_WIN32))
+  return()
+endif()
+
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json empty_dir_commands
+     REGEX "command.*-Winvalid-pch.*empty.dir/cmake_pch.h")
+file(STRINGS ${RunCMake_TEST_BINARY_DIR}/compile_commands.json foo_dir_commands
+     REGEX "command.*-Winvalid-pch.*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 -Winvalid-pch compile option present")
+  return()
+endif()
+
+if (foo_dir_commands_size GREATER 0)
+  set(RunCMake_TEST_FAILED "foo target should not have -Winvalid-pch compile option present")
+  return()
+endif()

+ 16 - 0
Tests/RunCMake/PrecompileHeaders/PchWarnInvalid.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_WARN_INVALID OFF)

+ 3 - 0
Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake

@@ -21,3 +21,6 @@ run_test(PchReuseFrom)
 run_test(PchReuseFromPrefixed)
 run_test(PchReuseFromSubdir)
 run_cmake(PchMultilanguage)
+if(RunCMake_GENERATOR MATCHES "Make|Ninja")
+  run_cmake(PchWarnInvalid)
+endif()