ソースを参照

Merge topic 'generate-target-order'

aea465793e cmLocalVisualStudio7Generator: Consolidate target iteration
1527242745 cmLocalVisualStudio10Generator: Simplify target ordering by dependencies
48bf7192e7 cmLocalVisualStudio7Generator: Generate targets in dependency order
17aba9c9a6 cmLocalUnixMakefileGenerator3: Generate targets in dependency order
69ee18163b cmLocalGhsMultiGenerator: Generate targets in dependency order
c4e296a609 cmGlobalGenerator: Compute a global target ordering respecting dependencies

Acked-by: Kitware Robot <[email protected]>
Merge-request: !5187
Brad King 5 年 前
コミット
503d0f80e1

+ 46 - 0
Source/cmGlobalGenerator.cxx

@@ -1471,6 +1471,7 @@ bool cmGlobalGenerator::Compute()
   if (!this->ComputeTargetDepends()) {
   if (!this->ComputeTargetDepends()) {
     return false;
     return false;
   }
   }
+  this->ComputeTargetOrder();
 
 
   if (this->CheckTargetsForType()) {
   if (this->CheckTargetsForType()) {
     return false;
     return false;
@@ -1581,6 +1582,50 @@ bool cmGlobalGenerator::ComputeTargetDepends()
   return true;
   return true;
 }
 }
 
 
+std::vector<cmGeneratorTarget*>
+cmGlobalGenerator::GetLocalGeneratorTargetsInOrder(cmLocalGenerator* lg) const
+{
+  std::vector<cmGeneratorTarget*> gts;
+  cm::append(gts, lg->GetGeneratorTargets());
+  std::sort(gts.begin(), gts.end(),
+            [this](cmGeneratorTarget const* l, cmGeneratorTarget const* r) {
+              return this->TargetOrderIndex.at(l) <
+                this->TargetOrderIndex.at(r);
+            });
+  return gts;
+}
+
+void cmGlobalGenerator::ComputeTargetOrder()
+{
+  size_t index = 0;
+  auto const& lgens = this->GetLocalGenerators();
+  for (auto const& lgen : lgens) {
+    const auto& targets = lgen->GetGeneratorTargets();
+    for (const auto& gt : targets) {
+      this->ComputeTargetOrder(gt.get(), index);
+    }
+  }
+  assert(index == this->TargetOrderIndex.size());
+}
+
+void cmGlobalGenerator::ComputeTargetOrder(cmGeneratorTarget const* gt,
+                                           size_t& index)
+{
+  std::map<cmGeneratorTarget const*, size_t>::value_type value(gt, 0);
+  auto insertion = this->TargetOrderIndex.insert(value);
+  if (!insertion.second) {
+    return;
+  }
+  auto entry = insertion.first;
+
+  auto& deps = this->GetTargetDirectDepends(gt);
+  for (auto& d : deps) {
+    this->ComputeTargetOrder(d, index);
+  }
+
+  entry->second = index++;
+}
+
 bool cmGlobalGenerator::QtAutoGen()
 bool cmGlobalGenerator::QtAutoGen()
 {
 {
 #ifndef CMAKE_BOOTSTRAP
 #ifndef CMAKE_BOOTSTRAP
@@ -1760,6 +1805,7 @@ void cmGlobalGenerator::ClearGeneratorMembers()
   this->GeneratorTargetSearchIndex.clear();
   this->GeneratorTargetSearchIndex.clear();
   this->MakefileSearchIndex.clear();
   this->MakefileSearchIndex.clear();
   this->LocalGeneratorSearchIndex.clear();
   this->LocalGeneratorSearchIndex.clear();
+  this->TargetOrderIndex.clear();
   this->ProjectMap.clear();
   this->ProjectMap.clear();
   this->RuleHashes.clear();
   this->RuleHashes.clear();
   this->DirectoryContentMap.clear();
   this->DirectoryContentMap.clear();

+ 8 - 0
Source/cmGlobalGenerator.h

@@ -4,6 +4,7 @@
 
 
 #include "cmConfigure.h" // IWYU pragma: keep
 #include "cmConfigure.h" // IWYU pragma: keep
 
 
+#include <cstddef>
 #include <iosfwd>
 #include <iosfwd>
 #include <map>
 #include <map>
 #include <memory>
 #include <memory>
@@ -264,6 +265,9 @@ public:
     return this->LocalGenerators;
     return this->LocalGenerators;
   }
   }
 
 
+  std::vector<cmGeneratorTarget*> GetLocalGeneratorTargetsInOrder(
+    cmLocalGenerator* lg) const;
+
   cmMakefile* GetCurrentMakefile() const
   cmMakefile* GetCurrentMakefile() const
   {
   {
     return this->CurrentConfigureMakefile;
     return this->CurrentConfigureMakefile;
@@ -613,6 +617,10 @@ private:
   // Its order is not deterministic.
   // Its order is not deterministic.
   LocalGeneratorMap LocalGeneratorSearchIndex;
   LocalGeneratorMap LocalGeneratorSearchIndex;
 
 
+  void ComputeTargetOrder();
+  void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index);
+  std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
+
   cmMakefile* TryCompileOuterMakefile;
   cmMakefile* TryCompileOuterMakefile;
   // If you add a new map here, make sure it is copied
   // If you add a new map here, make sure it is copied
   // in EnableLanguagesFromGenerator
   // in EnableLanguagesFromGenerator

+ 2 - 39
Source/cmGlobalXCodeGenerator.cxx

@@ -424,37 +424,6 @@ void cmGlobalXCodeGenerator::AddExtraIDETargets()
   }
   }
 }
 }
 
 
-void cmGlobalXCodeGenerator::ComputeTargetOrder()
-{
-  size_t index = 0;
-  auto const& lgens = this->GetLocalGenerators();
-  for (auto const& lgen : lgens) {
-    const auto& targets = lgen->GetGeneratorTargets();
-    for (const auto& gt : targets) {
-      this->ComputeTargetOrder(gt.get(), index);
-    }
-  }
-  assert(index == this->TargetOrderIndex.size());
-}
-
-void cmGlobalXCodeGenerator::ComputeTargetOrder(cmGeneratorTarget const* gt,
-                                                size_t& index)
-{
-  std::map<cmGeneratorTarget const*, size_t>::value_type value(gt, 0);
-  auto insertion = this->TargetOrderIndex.insert(value);
-  if (!insertion.second) {
-    return;
-  }
-  auto entry = insertion.first;
-
-  auto& deps = this->GetTargetDirectDepends(gt);
-  for (auto& d : deps) {
-    this->ComputeTargetOrder(d, index);
-  }
-
-  entry->second = index++;
-}
-
 void cmGlobalXCodeGenerator::Generate()
 void cmGlobalXCodeGenerator::Generate()
 {
 {
   this->cmGlobalGenerator::Generate();
   this->cmGlobalGenerator::Generate();
@@ -462,8 +431,6 @@ void cmGlobalXCodeGenerator::Generate()
     return;
     return;
   }
   }
 
 
-  this->ComputeTargetOrder();
-
   for (auto keyVal : this->ProjectMap) {
   for (auto keyVal : this->ProjectMap) {
     cmLocalGenerator* root = keyVal.second[0];
     cmLocalGenerator* root = keyVal.second[0];
 
 
@@ -1243,12 +1210,8 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
   cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets)
   cmLocalGenerator* gen, std::vector<cmXCodeObject*>& targets)
 {
 {
   this->SetCurrentLocalGenerator(gen);
   this->SetCurrentLocalGenerator(gen);
-  std::vector<cmGeneratorTarget*> gts;
-  cm::append(gts, this->CurrentLocalGenerator->GetGeneratorTargets());
-  std::sort(gts.begin(), gts.end(),
-            [this](cmGeneratorTarget const* l, cmGeneratorTarget const* r) {
-              return this->TargetOrderIndex[l] < this->TargetOrderIndex[r];
-            });
+  std::vector<cmGeneratorTarget*> gts =
+    this->GetLocalGeneratorTargetsInOrder(gen);
   for (auto gtgt : gts) {
   for (auto gtgt : gts) {
     if (!this->CreateXCodeTarget(gtgt, targets)) {
     if (!this->CreateXCodeTarget(gtgt, targets)) {
       return false;
       return false;

+ 0 - 3
Source/cmGlobalXCodeGenerator.h

@@ -115,8 +115,6 @@ public:
 
 
 protected:
 protected:
   void AddExtraIDETargets() override;
   void AddExtraIDETargets() override;
-  void ComputeTargetOrder();
-  void ComputeTargetOrder(cmGeneratorTarget const* gt, size_t& index);
   void Generate() override;
   void Generate() override;
 
 
 private:
 private:
@@ -303,7 +301,6 @@ private:
   std::string ObjectDirArch;
   std::string ObjectDirArch;
   std::string SystemName;
   std::string SystemName;
   std::string GeneratorToolset;
   std::string GeneratorToolset;
-  std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
   std::vector<std::string> EnabledLangs;
   std::vector<std::string> EnabledLangs;
   std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>>
   std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>>
     CommandsVisited;
     CommandsVisited;

+ 8 - 28
Source/cmLocalGhsMultiGenerator.cxx

@@ -2,10 +2,8 @@
    file Copyright.txt or https://cmake.org/licensing for details.  */
    file Copyright.txt or https://cmake.org/licensing for details.  */
 #include "cmLocalGhsMultiGenerator.h"
 #include "cmLocalGhsMultiGenerator.h"
 
 
-#include <algorithm>
 #include <utility>
 #include <utility>
-
-#include <cmext/algorithm>
+#include <vector>
 
 
 #include "cmGeneratorTarget.h"
 #include "cmGeneratorTarget.h"
 #include "cmGhsMultiTargetGenerator.h"
 #include "cmGhsMultiTargetGenerator.h"
@@ -29,34 +27,16 @@ std::string cmLocalGhsMultiGenerator::GetTargetDirectory(
   return dir;
   return dir;
 }
 }
 
 
-void cmLocalGhsMultiGenerator::GenerateTargetsDepthFirst(
-  cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
-{
-  if (!target->IsInBuildSystem()) {
-    return;
-  }
-  // Find this target in the list of remaining targets.
-  auto it = std::find(remaining.begin(), remaining.end(), target);
-  if (it == remaining.end()) {
-    // This target was already handled.
-    return;
-  }
-  // Remove this target from the list of remaining targets because
-  // we are handling it now.
-  *it = nullptr;
-
-  cmGhsMultiTargetGenerator tg(target);
-  tg.Generate();
-}
-
 void cmLocalGhsMultiGenerator::Generate()
 void cmLocalGhsMultiGenerator::Generate()
 {
 {
-  std::vector<cmGeneratorTarget*> remaining;
-  cm::append(remaining, this->GetGeneratorTargets());
-  for (auto& t : remaining) {
-    if (t) {
-      this->GenerateTargetsDepthFirst(t, remaining);
+  for (cmGeneratorTarget* gt :
+       this->GlobalGenerator->GetLocalGeneratorTargetsInOrder(this)) {
+    if (!gt->IsInBuildSystem()) {
+      continue;
     }
     }
+
+    cmGhsMultiTargetGenerator tg(gt);
+    tg.Generate();
   }
   }
 }
 }
 
 

+ 0 - 5
Source/cmLocalGhsMultiGenerator.h

@@ -4,7 +4,6 @@
 
 
 #include <map>
 #include <map>
 #include <string>
 #include <string>
-#include <vector>
 
 
 #include "cmLocalGenerator.h"
 #include "cmLocalGenerator.h"
 
 
@@ -37,8 +36,4 @@ public:
   void ComputeObjectFilenames(
   void ComputeObjectFilenames(
     std::map<cmSourceFile const*, std::string>& mapping,
     std::map<cmSourceFile const*, std::string>& mapping,
     cmGeneratorTarget const* gt = nullptr) override;
     cmGeneratorTarget const* gt = nullptr) override;
-
-private:
-  void GenerateTargetsDepthFirst(cmGeneratorTarget* target,
-                                 std::vector<cmGeneratorTarget*>& remaining);
 };
 };

+ 4 - 3
Source/cmLocalUnixMakefileGenerator3.cxx

@@ -100,12 +100,13 @@ void cmLocalUnixMakefileGenerator3::Generate()
   // Generate the rule files for each target.
   // Generate the rule files for each target.
   cmGlobalUnixMakefileGenerator3* gg =
   cmGlobalUnixMakefileGenerator3* gg =
     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
     static_cast<cmGlobalUnixMakefileGenerator3*>(this->GlobalGenerator);
-  for (const auto& target : this->GetGeneratorTargets()) {
-    if (!target->IsInBuildSystem()) {
+  for (cmGeneratorTarget* gt :
+       this->GlobalGenerator->GetLocalGeneratorTargetsInOrder(this)) {
+    if (!gt->IsInBuildSystem()) {
       continue;
       continue;
     }
     }
     std::unique_ptr<cmMakefileTargetGenerator> tg(
     std::unique_ptr<cmMakefileTargetGenerator> tg(
-      cmMakefileTargetGenerator::New(target.get()));
+      cmMakefileTargetGenerator::New(gt));
     if (tg) {
     if (tg) {
       tg->WriteRuleFiles();
       tg->WriteRuleFiles();
       gg->RecordTargetProgress(tg.get());
       gg->RecordTargetProgress(tg.get());

+ 5 - 32
Source/cmLocalVisualStudio10Generator.cxx

@@ -66,33 +66,18 @@ cmLocalVisualStudio10Generator::~cmLocalVisualStudio10Generator()
 {
 {
 }
 }
 
 
-void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
-  cmGeneratorTarget* target, std::vector<cmGeneratorTarget*>& remaining)
+void cmLocalVisualStudio10Generator::GenerateTarget(cmGeneratorTarget* target)
 {
 {
-  if (!target->IsInBuildSystem()) {
-    return;
-  }
-  // Find this target in the list of remaining targets.
-  auto it = std::find(remaining.begin(), remaining.end(), target);
-  if (it == remaining.end()) {
-    // This target was already handled.
-    return;
-  }
-  // Remove this target from the list of remaining targets because
-  // we are handling it now.
-  *it = nullptr;
+  auto& targetVisited = this->GetSourcesVisited(target);
   auto& deps = this->GlobalGenerator->GetTargetDirectDepends(target);
   auto& deps = this->GlobalGenerator->GetTargetDirectDepends(target);
   for (auto& d : deps) {
   for (auto& d : deps) {
-    // FIXME: Revise CreateSingleVCProj so we do not have to drop `const` here.
-    auto dependee = const_cast<cmGeneratorTarget*>(&*d);
-    GenerateTargetsDepthFirst(dependee, remaining);
     // Take the union of visited source files of custom commands
     // Take the union of visited source files of custom commands
-    auto visited = GetSourcesVisited(dependee);
-    GetSourcesVisited(target).insert(visited.begin(), visited.end());
+    auto depVisited = this->GetSourcesVisited(d);
+    targetVisited.insert(depVisited.begin(), depVisited.end());
   }
   }
   if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
   if (static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
         ->TargetIsFortranOnly(target)) {
         ->TargetIsFortranOnly(target)) {
-    this->CreateSingleVCProj(target->GetName(), target);
+    this->cmLocalVisualStudio7Generator::GenerateTarget(target);
   } else {
   } else {
     cmVisualStudio10TargetGenerator tg(
     cmVisualStudio10TargetGenerator tg(
       target,
       target,
@@ -102,18 +87,6 @@ void cmLocalVisualStudio10Generator::GenerateTargetsDepthFirst(
   }
   }
 }
 }
 
 
-void cmLocalVisualStudio10Generator::Generate()
-{
-  std::vector<cmGeneratorTarget*> remaining;
-  cm::append(remaining, this->GetGeneratorTargets());
-  for (auto& t : remaining) {
-    if (t) {
-      this->GenerateTargetsDepthFirst(t, remaining);
-    }
-  }
-  this->WriteStampFiles();
-}
-
 void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
 void cmLocalVisualStudio10Generator::ReadAndStoreExternalGUID(
   const std::string& name, const char* path)
   const std::string& name, const char* path)
 {
 {

+ 5 - 8
Source/cmLocalVisualStudio10Generator.h

@@ -25,14 +25,11 @@ public:
 
 
   virtual ~cmLocalVisualStudio10Generator();
   virtual ~cmLocalVisualStudio10Generator();
 
 
-  /**
-   * Generate the makefile for this directory.
-   */
-  void Generate() override;
   void ReadAndStoreExternalGUID(const std::string& name,
   void ReadAndStoreExternalGUID(const std::string& name,
                                 const char* path) override;
                                 const char* path) override;
 
 
-  std::set<cmSourceFile const*>& GetSourcesVisited(cmGeneratorTarget* target)
+  std::set<cmSourceFile const*>& GetSourcesVisited(
+    cmGeneratorTarget const* target)
   {
   {
     return SourcesVisited[target];
     return SourcesVisited[target];
   };
   };
@@ -42,8 +39,8 @@ protected:
   bool CustomCommandUseLocal() const override { return true; }
   bool CustomCommandUseLocal() const override { return true; }
 
 
 private:
 private:
-  void GenerateTargetsDepthFirst(cmGeneratorTarget* target,
-                                 std::vector<cmGeneratorTarget*>& remaining);
+  void GenerateTarget(cmGeneratorTarget* target) override;
 
 
-  std::map<cmGeneratorTarget*, std::set<cmSourceFile const*>> SourcesVisited;
+  std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>>
+    SourcesVisited;
 };
 };

+ 11 - 32
Source/cmLocalVisualStudio7Generator.cxx

@@ -80,7 +80,15 @@ void cmLocalVisualStudio7Generator::AddHelperCommands()
 
 
 void cmLocalVisualStudio7Generator::Generate()
 void cmLocalVisualStudio7Generator::Generate()
 {
 {
-  this->WriteProjectFiles();
+  // Create the project file for each target.
+  for (cmGeneratorTarget* gt :
+       this->GlobalGenerator->GetLocalGeneratorTargetsInOrder(this)) {
+    if (!gt->IsInBuildSystem() || gt->GetProperty("EXTERNAL_MSPROJECT")) {
+      continue;
+    }
+    this->GenerateTarget(gt);
+  }
+
   this->WriteStampFiles();
   this->WriteStampFiles();
 }
 }
 
 
@@ -111,35 +119,6 @@ void cmLocalVisualStudio7Generator::FixGlobalTargets()
   }
   }
 }
 }
 
 
-// TODO
-// for CommandLine= need to repleace quotes with &quot
-// write out configurations
-void cmLocalVisualStudio7Generator::WriteProjectFiles()
-{
-  // If not an in source build, then create the output directory
-  if (this->GetCurrentBinaryDirectory() != this->GetSourceDirectory()) {
-    if (!cmSystemTools::MakeDirectory(this->GetCurrentBinaryDirectory())) {
-      cmSystemTools::Error("Error creating directory " +
-                           this->GetCurrentBinaryDirectory());
-    }
-  }
-
-  // Get the set of targets in this directory.
-  const auto& tgts = this->GetGeneratorTargets();
-
-  // Create the project file for each target.
-  for (const auto& l : tgts) {
-    if (!l->IsInBuildSystem()) {
-      continue;
-    }
-    // INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
-    // so don't build a projectfile for it
-    if (!l->GetProperty("EXTERNAL_MSPROJECT")) {
-      this->CreateSingleVCProj(l->GetName(), l.get());
-    }
-  }
-}
-
 void cmLocalVisualStudio7Generator::WriteStampFiles()
 void cmLocalVisualStudio7Generator::WriteStampFiles()
 {
 {
   // Touch a timestamp file used to determine when the project file is
   // Touch a timestamp file used to determine when the project file is
@@ -178,9 +157,9 @@ void cmLocalVisualStudio7Generator::WriteStampFiles()
   }
   }
 }
 }
 
 
-void cmLocalVisualStudio7Generator::CreateSingleVCProj(
-  const std::string& lname, cmGeneratorTarget* target)
+void cmLocalVisualStudio7Generator::GenerateTarget(cmGeneratorTarget* target)
 {
 {
+  std::string const& lname = target->GetName();
   cmGlobalVisualStudioGenerator* gg =
   cmGlobalVisualStudioGenerator* gg =
     static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
     static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
   this->FortranProject = gg->TargetIsFortranOnly(target);
   this->FortranProject = gg->TargetIsFortranOnly(target);

+ 1 - 2
Source/cmLocalVisualStudio7Generator.h

@@ -84,7 +84,7 @@ public:
                                         const char* path);
                                         const char* path);
 
 
 protected:
 protected:
-  void CreateSingleVCProj(const std::string& lname, cmGeneratorTarget* tgt);
+  virtual void GenerateTarget(cmGeneratorTarget* target);
 
 
 private:
 private:
   using Options = cmVS7GeneratorOptions;
   using Options = cmVS7GeneratorOptions;
@@ -92,7 +92,6 @@ private:
   std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
   std::string GetBuildTypeLinkerFlags(std::string rootLinkerFlags,
                                       const std::string& configName);
                                       const std::string& configName);
   void FixGlobalTargets();
   void FixGlobalTargets();
-  void WriteProjectFiles();
   void WriteVCProjHeader(std::ostream& fout, const std::string& libName,
   void WriteVCProjHeader(std::ostream& fout, const std::string& libName,
                          cmGeneratorTarget* tgt,
                          cmGeneratorTarget* tgt,
                          std::vector<cmSourceGroup>& sgs);
                          std::vector<cmSourceGroup>& sgs);

+ 0 - 4
Source/cmVisualStudio10TargetGenerator.cxx

@@ -314,10 +314,6 @@ std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
 
 
 void cmVisualStudio10TargetGenerator::Generate()
 void cmVisualStudio10TargetGenerator::Generate()
 {
 {
-  // do not generate external ms projects
-  if (this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
-    return;
-  }
   const std::string ProjectFileExtension =
   const std::string ProjectFileExtension =
     computeProjectFileExtension(this->GeneratorTarget);
     computeProjectFileExtension(this->GeneratorTarget);
   if (ProjectFileExtension == ".vcxproj") {
   if (ProjectFileExtension == ".vcxproj") {