ソースを参照

cmLocalGenerator: ignore scanned sources for unity builds

Ben Boeckel 1 年間 前
コミット
63bbb3768d

+ 4 - 0
Help/manual/cmake-cxxmodules.7.rst

@@ -30,6 +30,10 @@ following queries. The first query that provides a yes/no answer is used.
 - Otherwise, the source file will be scanned if the compiler and generator
   support scanning.  See policy :policy:`CMP0155`.
 
+Note that any scanned source will be excluded from any unity build (see
+:prop_tgt:`UNITY_BUILD`) because module-related statements can only happen at
+one place within a C++ translation unit.
+
 Compiler Support
 ================
 

+ 4 - 0
Help/prop_sf/SKIP_UNITY_BUILD_INCLUSION.rst

@@ -11,3 +11,7 @@ in the same way as it would with unity builds disabled.
 This property helps with "ODR (One definition rule)" problems where combining
 a particular source file with others might lead to build errors or other
 unintended side effects.
+
+Note that sources which are scanned for C++ modules (see
+:manual:`cmake-cxxmodules(7)`) are not eligible for unity build inclusion and
+will automatically be excluded.

+ 5 - 0
Help/prop_tgt/UNITY_BUILD.rst

@@ -64,6 +64,11 @@ a number of measures to help address such problems:
   :prop_sf:`INCLUDE_DIRECTORIES` source property will not be combined
   into a unity source.
 
+* Any source file which is scanned for C++ module sources via
+  :prop_tgt:`CXX_SCAN_FOR_MODULES`, :prop_sf:`CXX_SCAN_FOR_MODULES`, or
+  membership of a ``CXX_MODULES`` file set will not be combined into a unity
+  source.  See :manual:`cmake-cxxmodules(7)` for details.
+
 * Projects can prevent an individual source file from being combined into
   a unity source by setting its :prop_sf:`SKIP_UNITY_BUILD_INCLUSION`
   source property to true.  This can be a more effective way to prevent

+ 9 - 0
Source/cmLocalGenerator.cxx

@@ -3134,6 +3134,15 @@ void cmLocalGenerator::AddUnityBuild(cmGeneratorTarget* target)
     std::vector<cmSourceFile*> sources;
     target->GetSourceFiles(sources, configs[ci]);
     for (cmSourceFile* sf : sources) {
+      // Files which need C++ scanning cannot participate in unity builds as
+      // there is a single place in TUs that may perform module-dependency bits
+      // and a unity source cannot `#include` them in-order and represent a
+      // valid TU.
+      if (sf->GetLanguage() == "CXX"_s &&
+          target->NeedDyndepForSource("CXX", configs[ci], sf)) {
+        continue;
+      }
+
       auto mi = index.find(sf);
       if (mi == index.end()) {
         unitySources.emplace_back(sf);