Browse Source

cmLocalGenerator: ignore scanned sources for unity builds

Ben Boeckel 1 year ago
parent
commit
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
 - Otherwise, the source file will be scanned if the compiler and generator
   support scanning.  See policy :policy:`CMP0155`.
   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
 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
 This property helps with "ODR (One definition rule)" problems where combining
 a particular source file with others might lead to build errors or other
 a particular source file with others might lead to build errors or other
 unintended side effects.
 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
   :prop_sf:`INCLUDE_DIRECTORIES` source property will not be combined
   into a unity source.
   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
 * Projects can prevent an individual source file from being combined into
   a unity source by setting its :prop_sf:`SKIP_UNITY_BUILD_INCLUSION`
   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
   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;
     std::vector<cmSourceFile*> sources;
     target->GetSourceFiles(sources, configs[ci]);
     target->GetSourceFiles(sources, configs[ci]);
     for (cmSourceFile* sf : sources) {
     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);
       auto mi = index.find(sf);
       if (mi == index.end()) {
       if (mi == index.end()) {
         unitySources.emplace_back(sf);
         unitySources.emplace_back(sf);