Parcourir la source

cmLocalGenerator: Refactor custom command generator construction

Add support for constructing and using multiple generators for one
custom command.  cmGeneratorTarget contains a code path that needs this
behavior when used with Ninja but not other generators, so use virtual
dispatch through cmLocalGenerator.
Brad King il y a 5 ans
Parent
commit
7b64b0cd5a

+ 8 - 7
Source/cmGeneratorTarget.cxx

@@ -3079,15 +3079,16 @@ void cmTargetTraceDependencies::CheckCustomCommand(cmCustomCommand const& cc)
   std::set<std::string> depends;
   std::set<std::string> depends;
   for (std::string const& config :
   for (std::string const& config :
        this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
        this->Makefile->GetGeneratorConfigs(cmMakefile::IncludeEmptyConfig)) {
-    cmCustomCommandGenerator ccg(cc, config, this->LocalGenerator);
+    for (cmCustomCommandGenerator const& ccg :
+         this->LocalGenerator->MakeCustomCommandGenerators(cc, config)) {
+      // Collect target-level dependencies referenced in command lines.
+      for (auto const& util : ccg.GetUtilities()) {
+        this->GeneratorTarget->Target->AddUtility(util);
+      }
 
 
-    // Collect target-level dependencies referenced in command lines.
-    for (auto const& util : ccg.GetUtilities()) {
-      this->GeneratorTarget->Target->AddUtility(util);
+      // Collect file-level dependencies referenced in DEPENDS.
+      depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end());
     }
     }
-
-    // Collect file-level dependencies referenced in DEPENDS.
-    depends.insert(ccg.GetDepends().begin(), ccg.GetDepends().end());
   }
   }
 
 
   // Queue file-level dependencies.
   // Queue file-level dependencies.

+ 9 - 0
Source/cmLocalGenerator.cxx

@@ -4232,6 +4232,15 @@ cmSourceFile* cmLocalGenerator::GetSourceFileWithOutput(
   return nullptr;
   return nullptr;
 }
 }
 
 
+std::vector<cmCustomCommandGenerator>
+cmLocalGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
+                                              std::string const& config)
+{
+  std::vector<cmCustomCommandGenerator> ccgs;
+  ccgs.emplace_back(cc, config, this);
+  return ccgs;
+}
+
 std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
 std::vector<std::string> cmLocalGenerator::ExpandCustomCommandOutputPaths(
   cmCompiledGeneratorExpression const& cge, std::string const& config)
   cmCompiledGeneratorExpression const& cge, std::string const& config)
 {
 {

+ 4 - 0
Source/cmLocalGenerator.h

@@ -24,6 +24,7 @@
 
 
 class cmCompiledGeneratorExpression;
 class cmCompiledGeneratorExpression;
 class cmComputeLinkInformation;
 class cmComputeLinkInformation;
+class cmCustomCommand;
 class cmCustomCommandGenerator;
 class cmCustomCommandGenerator;
 class cmCustomCommandLines;
 class cmCustomCommandLines;
 class cmGeneratorTarget;
 class cmGeneratorTarget;
@@ -363,6 +364,9 @@ public:
     bool command_expand_lists = false, const std::string& job_pool = "",
     bool command_expand_lists = false, const std::string& job_pool = "",
     bool stdPipesUTF8 = false);
     bool stdPipesUTF8 = false);
 
 
+  virtual std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
+    cmCustomCommand const& cc, std::string const& config);
+
   std::vector<std::string> ExpandCustomCommandOutputPaths(
   std::vector<std::string> ExpandCustomCommandOutputPaths(
     cmCompiledGeneratorExpression const& cge, std::string const& config);
     cmCompiledGeneratorExpression const& cge, std::string const& config);
   std::vector<std::string> ExpandCustomCommandOutputGenex(
   std::vector<std::string> ExpandCustomCommandOutputGenex(

+ 89 - 78
Source/cmLocalNinjaGenerator.cxx

@@ -575,97 +575,108 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
     return;
     return;
   }
   }
 
 
-  bool transformDepfile = false;
-  auto cmp0116 = this->GetPolicyStatus(cmPolicies::CMP0116);
-  switch (cmp0116) {
-    case cmPolicies::OLD:
-    case cmPolicies::WARN:
-      break;
-    case cmPolicies::REQUIRED_IF_USED:
-    case cmPolicies::REQUIRED_ALWAYS:
-    case cmPolicies::NEW:
-      transformDepfile = true;
-      break;
-  }
+  for (cmCustomCommandGenerator const& ccg :
+       this->MakeCustomCommandGenerators(*cc, config)) {
 
 
-  cmCustomCommandGenerator ccg(*cc, config, this, transformDepfile);
+    const std::vector<std::string>& outputs = ccg.GetOutputs();
+    const std::vector<std::string>& byproducts = ccg.GetByproducts();
 
 
-  const std::vector<std::string>& outputs = ccg.GetOutputs();
-  const std::vector<std::string>& byproducts = ccg.GetByproducts();
-
-  bool symbolic = false;
-  for (std::string const& output : outputs) {
-    if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
-      if (sf->GetPropertyAsBool("SYMBOLIC")) {
-        symbolic = true;
-        break;
+    bool symbolic = false;
+    for (std::string const& output : outputs) {
+      if (cmSourceFile* sf = this->Makefile->GetSource(output)) {
+        if (sf->GetPropertyAsBool("SYMBOLIC")) {
+          symbolic = true;
+          break;
+        }
       }
       }
     }
     }
-  }
 
 
-  cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
-  std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
-                 gg->MapToNinjaPath());
-  std::transform(byproducts.begin(), byproducts.end(),
-                 ninjaOutputs.begin() + outputs.size(), gg->MapToNinjaPath());
+    cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size());
+    std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(),
+                   gg->MapToNinjaPath());
+    std::transform(byproducts.begin(), byproducts.end(),
+                   ninjaOutputs.begin() + outputs.size(),
+                   gg->MapToNinjaPath());
 
 
-  for (std::string const& ninjaOutput : ninjaOutputs) {
-    gg->SeenCustomCommandOutput(ninjaOutput);
-  }
+    for (std::string const& ninjaOutput : ninjaOutputs) {
+      gg->SeenCustomCommandOutput(ninjaOutput);
+    }
 
 
-  cmNinjaDeps ninjaDeps;
-  this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
+    cmNinjaDeps ninjaDeps;
+    this->AppendCustomCommandDeps(ccg, ninjaDeps, config);
 
 
-  std::vector<std::string> cmdLines;
-  this->AppendCustomCommandLines(ccg, cmdLines);
+    std::vector<std::string> cmdLines;
+    this->AppendCustomCommandLines(ccg, cmdLines);
 
 
-  if (cmdLines.empty()) {
-    cmNinjaBuild build("phony");
-    build.Comment = "Phony custom command for " + ninjaOutputs[0];
-    build.Outputs = std::move(ninjaOutputs);
-    build.ExplicitDeps = std::move(ninjaDeps);
-    build.OrderOnlyDeps = orderOnlyDeps;
-    gg->WriteBuild(this->GetImplFileStream(config), build);
-  } else {
-    std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
-    // Hash full path to make unique.
-    customStep += '-';
-    cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
-    customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
-
-    std::string depfile = cc->GetDepfile();
-    if (!depfile.empty()) {
-      switch (cmp0116) {
-        case cmPolicies::WARN:
-          if (this->GetCurrentBinaryDirectory() !=
-                this->GetBinaryDirectory() ||
-              this->Makefile->PolicyOptionalWarningEnabled(
-                "CMAKE_POLICY_WARNING_CMP0116")) {
-            this->GetCMakeInstance()->IssueMessage(
-              MessageType::AUTHOR_WARNING,
-              cmPolicies::GetPolicyWarning(cmPolicies::CMP0116),
-              cc->GetBacktrace());
-          }
-          CM_FALLTHROUGH;
-        case cmPolicies::OLD:
-          break;
-        case cmPolicies::REQUIRED_IF_USED:
-        case cmPolicies::REQUIRED_ALWAYS:
-        case cmPolicies::NEW:
-          cmSystemTools::MakeDirectory(
-            cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d"));
-          depfile = ccg.GetInternalDepfile();
-          break;
+    if (cmdLines.empty()) {
+      cmNinjaBuild build("phony");
+      build.Comment = "Phony custom command for " + ninjaOutputs[0];
+      build.Outputs = std::move(ninjaOutputs);
+      build.ExplicitDeps = std::move(ninjaDeps);
+      build.OrderOnlyDeps = orderOnlyDeps;
+      gg->WriteBuild(this->GetImplFileStream(config), build);
+    } else {
+      std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]);
+      // Hash full path to make unique.
+      customStep += '-';
+      cmCryptoHash hash(cmCryptoHash::AlgoSHA256);
+      customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7);
+
+      std::string depfile = cc->GetDepfile();
+      if (!depfile.empty()) {
+        switch (this->GetPolicyStatus(cmPolicies::CMP0116)) {
+          case cmPolicies::WARN:
+            if (this->GetCurrentBinaryDirectory() !=
+                  this->GetBinaryDirectory() ||
+                this->Makefile->PolicyOptionalWarningEnabled(
+                  "CMAKE_POLICY_WARNING_CMP0116")) {
+              this->GetCMakeInstance()->IssueMessage(
+                MessageType::AUTHOR_WARNING,
+                cmPolicies::GetPolicyWarning(cmPolicies::CMP0116),
+                cc->GetBacktrace());
+            }
+            CM_FALLTHROUGH;
+          case cmPolicies::OLD:
+            break;
+          case cmPolicies::REQUIRED_IF_USED:
+          case cmPolicies::REQUIRED_ALWAYS:
+          case cmPolicies::NEW:
+            cmSystemTools::MakeDirectory(
+              cmStrCat(this->GetBinaryDirectory(), "/CMakeFiles/d"));
+            depfile = ccg.GetInternalDepfile();
+            break;
+        }
       }
       }
+
+      gg->WriteCustomCommandBuild(
+        this->BuildCommandLine(cmdLines, customStep),
+        this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
+        depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
+        /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
+        ninjaDeps, orderOnlyDeps);
     }
     }
+  }
+}
 
 
-    gg->WriteCustomCommandBuild(
-      this->BuildCommandLine(cmdLines, customStep),
-      this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0],
-      depfile, cc->GetJobPool(), cc->GetUsesTerminal(),
-      /*restat*/ !symbolic || !byproducts.empty(), ninjaOutputs, config,
-      ninjaDeps, orderOnlyDeps);
+std::vector<cmCustomCommandGenerator>
+cmLocalNinjaGenerator::MakeCustomCommandGenerators(cmCustomCommand const& cc,
+                                                   std::string const& config)
+{
+  bool transformDepfile = false;
+  switch (this->GetPolicyStatus(cmPolicies::CMP0116)) {
+    case cmPolicies::OLD:
+    case cmPolicies::WARN:
+      break;
+    case cmPolicies::REQUIRED_IF_USED:
+    case cmPolicies::REQUIRED_ALWAYS:
+    case cmPolicies::NEW:
+      transformDepfile = true;
+      break;
   }
   }
+
+  std::vector<cmCustomCommandGenerator> ccgs;
+  ccgs.emplace_back(cc, config, this, transformDepfile);
+  return ccgs;
 }
 }
 
 
 void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,
 void cmLocalNinjaGenerator::AddCustomCommandTarget(cmCustomCommand const* cc,

+ 3 - 0
Source/cmLocalNinjaGenerator.h

@@ -70,6 +70,9 @@ public:
                            const std::string& fileConfig,
                            const std::string& fileConfig,
                            cmNinjaTargetDepends depends);
                            cmNinjaTargetDepends depends);
 
 
+  std::vector<cmCustomCommandGenerator> MakeCustomCommandGenerators(
+    cmCustomCommand const& cc, std::string const& config) override;
+
   void AddCustomCommandTarget(cmCustomCommand const* cc,
   void AddCustomCommandTarget(cmCustomCommand const* cc,
                               cmGeneratorTarget* target);
                               cmGeneratorTarget* target);
   void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,
   void AppendCustomCommandLines(cmCustomCommandGenerator const& ccg,