Переглянути джерело

cmGlobalGenerator: compute target features before synthetic targets

For `import std;` support, CMake needs to know the standard library
involved in order to ensure that the right target is linked. Afterwards,
the created synthetic targets need their target compile features
computed.
Ben Boeckel 1 рік тому
батько
коміт
15cd73d6c2
2 змінених файлів з 28 додано та 10 видалено
  1. 12 0
      Source/cmGeneratorTarget.cxx
  2. 16 10
      Source/cmGlobalGenerator.cxx

+ 12 - 0
Source/cmGeneratorTarget.cxx

@@ -8414,6 +8414,8 @@ void ComputeLinkImplTransitive(cmGeneratorTarget const* self,
 bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
                                                  std::string const& config)
 {
+  std::vector<std::string> allConfigs =
+    this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig);
   cmOptionalLinkImplementation impl;
   this->ComputeLinkImplementationLibraries(config, impl, this,
                                            LinkInterfaceFor::Link);
@@ -8488,9 +8490,19 @@ bool cmGeneratorTarget::DiscoverSyntheticTargets(cmSyntheticTargetCache& cache,
 
         // Create the generator target and attach it to the local generator.
         auto gtp = cm::make_unique<cmGeneratorTarget>(tgt, lg);
+
         synthDep = gtp.get();
         cache.CxxModuleTargets[targetName] = synthDep;
+
+        // See `localGen->ComputeTargetCompileFeatures()` call in
+        // `cmGlobalGenerator::Compute` for where non-synthetic targets resolve
+        // this.
+        for (auto const& innerConfig : allConfigs) {
+          gtp->ComputeCompileFeatures(innerConfig);
+        }
+
         gtp->DiscoverSyntheticTargets(cache, config);
+
         lg->AddGeneratorTarget(std::move(gtp));
       } else {
         synthDep = cached->second;

+ 16 - 10
Source/cmGlobalGenerator.cxx

@@ -1581,6 +1581,19 @@ bool cmGlobalGenerator::Compute()
   }
 #endif
 
+  // Perform up-front computation in order to handle errors (such as unknown
+  // features) at this point. While processing the compile features we also
+  // calculate and cache the language standard required by the compile
+  // features.
+  //
+  // Synthetic targets performed this inside of
+  // `cmLocalGenerator::DiscoverSyntheticTargets`
+  for (const auto& localGen : this->LocalGenerators) {
+    if (!localGen->ComputeTargetCompileFeatures()) {
+      return false;
+    }
+  }
+
   // Iterate through all targets and set up C++20 module targets.
   // Create target templates for each imported target with C++20 modules.
   // INTERFACE library with BMI-generating rules and a collation step?
@@ -1588,6 +1601,9 @@ bool cmGlobalGenerator::Compute()
   // Make `add_dependencies(imported_target
   // $<$<TARGET_NAME_IF_EXISTS:uses_imported>:synth1>
   // $<$<TARGET_NAME_IF_EXISTS:other_uses_imported>:synth2>)`
+  //
+  // Note that synthetic target creation performs the above marked
+  // steps on the created targets.
   if (!this->DiscoverSyntheticTargets()) {
     return false;
   }
@@ -1597,16 +1613,6 @@ bool cmGlobalGenerator::Compute()
     localGen->AddHelperCommands();
   }
 
-  // Perform up-front computation in order to handle errors (such as unknown
-  // features) at this point. While processing the compile features we also
-  // calculate and cache the language standard required by the compile
-  // features.
-  for (const auto& localGen : this->LocalGenerators) {
-    if (!localGen->ComputeTargetCompileFeatures()) {
-      return false;
-    }
-  }
-
   // Add automatically generated sources (e.g. unity build).
   // Add unity sources after computing compile features.  Unity sources do
   // not change the set of languages or features, but we need to know them