浏览代码

PCH: Fix all-language precompile header support in Xcode

Fixes: #22384
Cristian Adam 4 年之前
父节点
当前提交
bbcdac4e5d

+ 2 - 2
Source/cmGeneratorTarget.cxx

@@ -4100,7 +4100,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
         if (this->GetGlobalGenerator()->IsXcode()) {
           file << "#ifndef CMAKE_SKIP_PRECOMPILE_HEADERS\n";
         }
-        if (language == "CXX") {
+        if (language == "CXX" && !this->GetGlobalGenerator()->IsXcode()) {
           file << "#ifdef __cplusplus\n";
         }
         for (auto const& header_bt : headers) {
@@ -4118,7 +4118,7 @@ std::string cmGeneratorTarget::GetPchHeader(const std::string& config,
             firstHeaderOnDisk = header_bt.Value;
           }
         }
-        if (language == "CXX") {
+        if (language == "CXX" && !this->GetGlobalGenerator()->IsXcode()) {
           file << "#endif // __cplusplus\n";
         }
         if (this->GetGlobalGenerator()->IsXcode()) {

+ 15 - 0
Source/cmLocalGenerator.cxx

@@ -2512,6 +2512,16 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
     static const std::array<std::string, 4> langs = { { "C", "CXX", "OBJC",
                                                         "OBJCXX" } };
 
+    bool haveAnyPch = false;
+    if (this->GetGlobalGenerator()->IsXcode()) {
+      for (const std::string& lang : langs) {
+        const std::string pchHeader = target->GetPchHeader(config, lang, "");
+        if (!pchHeader.empty()) {
+          haveAnyPch = true;
+        }
+      }
+    }
+
     for (const std::string& lang : langs) {
       auto langSources = std::count_if(
         sources.begin(), sources.end(), [lang](cmSourceFile* sf) {
@@ -2552,6 +2562,11 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
         const std::string pchHeader = target->GetPchHeader(config, lang, arch);
 
         if (pchSource.empty() || pchHeader.empty()) {
+          if (this->GetGlobalGenerator()->IsXcode() && haveAnyPch) {
+            for (auto* sf : sources) {
+              sf->SetProperty("SKIP_PRECOMPILE_HEADERS", "ON");
+            }
+          }
           continue;
         }
 

+ 16 - 0
Tests/RunCMake/PrecompileHeaders/PchIncludedAllLanguages.cmake

@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.15)
+project(PchIncludedAllLanguages C CXX)
+
+if(CMAKE_CXX_COMPILE_OPTIONS_USE_PCH)
+  add_definitions(-DHAVE_PCH_SUPPORT)
+endif()
+
+add_executable(main
+  main.cpp
+  pch-included.c
+  pch-included.cpp
+)
+target_precompile_headers(main PRIVATE pch.h)
+
+enable_testing()
+add_test(NAME main COMMAND main)

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

@@ -28,3 +28,4 @@ if(RunCMake_GENERATOR MATCHES "Make|Ninja")
   endif()
 endif()
 run_test(PchReuseFromObjLib)
+run_test(PchIncludedAllLanguages)

+ 8 - 0
Tests/RunCMake/PrecompileHeaders/pch-included.c

@@ -0,0 +1,8 @@
+#ifndef HAVE_PCH_SUPPORT
+#  include "pch.h"
+#endif
+
+int testC(void)
+{
+  return PCH_INCLUDED;
+}

+ 8 - 0
Tests/RunCMake/PrecompileHeaders/pch-included.cpp

@@ -0,0 +1,8 @@
+#ifndef HAVE_PCH_SUPPORT
+#  include "pch.h"
+#endif
+
+int testCpp()
+{
+  return PCH_INCLUDED;
+}

+ 2 - 0
Tests/RunCMake/PrecompileHeaders/pch.h

@@ -1,3 +1,5 @@
 #pragma once
 
 #define PCH_INCLUDED 1
+
+int testC(void);