From d9fd32b3b347327adb146284b543ec8e97cae6bd Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Fri, 19 Feb 2021 11:21:28 -0500
Subject: cmVisualStudio10TargetGenerator: Refactor per-source PCH logic

De-duplicate the link language lookup.
---
 Source/cmVisualStudio10TargetGenerator.cxx | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index a93a78a..50a456d 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2413,16 +2413,16 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
     // 1. We have SKIP_PRECOMPILE_HEADERS == true
     // 2. We are creating the pre-compiled header
     // 3. We are a different language than the linker language AND pch is
-    // enabled
-    const std::string pchSource =
+    //    enabled.
+    std::string const& linkLanguage =
+      this->GeneratorTarget->GetLinkerLanguage(config);
+    std::string const& pchSource =
       this->GeneratorTarget->GetPchSource(config, lang);
     const bool skipPCH =
       pchSource.empty() || sf.GetPropertyAsBool("SKIP_PRECOMPILE_HEADERS");
     const bool makePCH = (sf.GetFullPath() == pchSource);
-    const bool useSharedPCH =
-      !skipPCH && (lang == this->GeneratorTarget->GetLinkerLanguage(config));
-    const bool useDifferentLangPCH =
-      !skipPCH && (lang != this->GeneratorTarget->GetLinkerLanguage(config));
+    const bool useSharedPCH = !skipPCH && (lang == linkLanguage);
+    const bool useDifferentLangPCH = !skipPCH && (lang != linkLanguage);
     const bool needsPCHFlags =
       (makePCH || useSharedPCH || useDifferentLangPCH);
 
-- 
cgit v0.12


From 9945b3b5655a8cefc0a0fb43bdb1948b6ab5bc32 Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Fri, 19 Feb 2021 11:25:26 -0500
Subject: VS: Restore support for PCH in CXX but not C within once target

Fix logic from commit 9df1f33c9a (VisualStudio: move PCH rules to
projects when possible., 2020-10-15, v3.20.0-rc1~638^2) to explicitly
disable PCH on sources that should not use the target-wide PCH rules.

Fixes: #21827
---
 Source/cmVisualStudio10TargetGenerator.cxx          |  6 +++++-
 Tests/RunCMake/PrecompileHeaders/CXXnotC.cmake      | 15 +++++++++++++++
 Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake |  1 +
 Tests/RunCMake/PrecompileHeaders/include/cxx_pch.h  |  1 +
 Tests/RunCMake/PrecompileHeaders/no_pch.c           |  7 +++++++
 Tests/RunCMake/PrecompileHeaders/use_pch.cxx        |  9 +++++++++
 6 files changed, 38 insertions(+), 1 deletion(-)
 create mode 100644 Tests/RunCMake/PrecompileHeaders/CXXnotC.cmake
 create mode 100644 Tests/RunCMake/PrecompileHeaders/include/cxx_pch.h
 create mode 100644 Tests/RunCMake/PrecompileHeaders/no_pch.c
 create mode 100644 Tests/RunCMake/PrecompileHeaders/use_pch.cxx

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 50a456d..6a90675 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -2423,8 +2423,10 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
     const bool makePCH = (sf.GetFullPath() == pchSource);
     const bool useSharedPCH = !skipPCH && (lang == linkLanguage);
     const bool useDifferentLangPCH = !skipPCH && (lang != linkLanguage);
+    const bool useNoPCH = skipPCH && (lang != linkLanguage) &&
+      !this->GeneratorTarget->GetPchHeader(config, linkLanguage).empty();
     const bool needsPCHFlags =
-      (makePCH || useSharedPCH || useDifferentLangPCH);
+      (makePCH || useSharedPCH || useDifferentLangPCH || useNoPCH);
 
     // if we have flags or defines for this config then
     // use them
@@ -2471,6 +2473,8 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
         if (makePCH) {
           pchOptions =
             this->GeneratorTarget->GetPchCreateCompileOptions(config, lang);
+        } else if (useNoPCH) {
+          clOptions.AddFlag("PrecompiledHeader", "NotUsing");
         } else if (useSharedPCH) {
           std::string pchHeader =
             this->GeneratorTarget->GetPchHeader(config, lang);
diff --git a/Tests/RunCMake/PrecompileHeaders/CXXnotC.cmake b/Tests/RunCMake/PrecompileHeaders/CXXnotC.cmake
new file mode 100644
index 0000000..9ec1b36
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/CXXnotC.cmake
@@ -0,0 +1,15 @@
+enable_language(C)
+enable_language(CXX)
+
+add_executable(main
+  no_pch.c
+  use_pch.cxx
+)
+
+target_include_directories(main PUBLIC include)
+target_precompile_headers(main PRIVATE
+  "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/include/cxx_pch.h>"
+  )
+
+enable_testing()
+add_test(NAME main COMMAND main)
diff --git a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
index a5a3770..8cc59d2 100644
--- a/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
+++ b/Tests/RunCMake/PrecompileHeaders/RunCMakeTest.cmake
@@ -14,6 +14,7 @@ run_cmake(PchDebugGenex)
 run_test(PchInterface)
 run_cmake(PchPrologueEpilogue)
 run_test(SkipPrecompileHeaders)
+run_test(CXXnotC)
 run_test(PchReuseFrom)
 run_test(PchReuseFromPrefixed)
 run_test(PchReuseFromSubdir)
diff --git a/Tests/RunCMake/PrecompileHeaders/include/cxx_pch.h b/Tests/RunCMake/PrecompileHeaders/include/cxx_pch.h
new file mode 100644
index 0000000..3282cec
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/include/cxx_pch.h
@@ -0,0 +1 @@
+#define CXX_PCH
diff --git a/Tests/RunCMake/PrecompileHeaders/no_pch.c b/Tests/RunCMake/PrecompileHeaders/no_pch.c
new file mode 100644
index 0000000..8d22580
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/no_pch.c
@@ -0,0 +1,7 @@
+#ifdef CXX_PCH
+#  error "CXX PCH included in C source."
+#endif
+int no_pch(void)
+{
+  return 0;
+}
diff --git a/Tests/RunCMake/PrecompileHeaders/use_pch.cxx b/Tests/RunCMake/PrecompileHeaders/use_pch.cxx
new file mode 100644
index 0000000..caf115b
--- /dev/null
+++ b/Tests/RunCMake/PrecompileHeaders/use_pch.cxx
@@ -0,0 +1,9 @@
+#include "cxx_pch.h"
+#ifndef CXX_PCH
+#  error "CXX PCH not included in CXX source."
+#endif
+extern "C" int no_pch(void);
+int main()
+{
+  return no_pch();
+}
-- 
cgit v0.12