瀏覽代碼

Merge topic 'xcode-custom-commands'

e33f8f078a Xcode: Avoid unnecessary duplication of custom commands across targets
8c60c49ae2 Xcode: Refactor custom command dependency expansion

Acked-by: Kitware Robot <[email protected]>
Merge-request: !5176
Brad King 5 年之前
父節點
當前提交
68b674b8bc
共有 2 個文件被更改,包括 37 次插入7 次删除
  1. 35 7
      Source/cmGlobalXCodeGenerator.cxx
  2. 2 0
      Source/cmGlobalXCodeGenerator.h

+ 35 - 7
Source/cmGlobalXCodeGenerator.cxx

@@ -679,6 +679,7 @@ void cmGlobalXCodeGenerator::ClearXCodeObjects()
   this->FileRefs.clear();
   this->ExternalLibRefs.clear();
   this->FileRefToBuildFileMap.clear();
+  this->CommandsVisited.clear();
 }
 
 void cmGlobalXCodeGenerator::addObject(std::unique_ptr<cmXCodeObject> obj)
@@ -1271,6 +1272,16 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
     return true;
   }
 
+  auto& gtgt_visited = this->CommandsVisited[gtgt];
+  auto& deps = this->GetTargetDirectDepends(gtgt);
+  for (auto& d : deps) {
+    // Take the union of visited source files of custom commands so far.
+    // ComputeTargetOrder ensures our dependencies already visited their
+    // custom commands and updated CommandsVisited.
+    auto& dep_visited = this->CommandsVisited[d];
+    gtgt_visited.insert(dep_visited.begin(), dep_visited.end());
+  }
+
   if (gtgt->GetType() == cmStateEnums::UTILITY ||
       gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
       gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
@@ -1628,8 +1639,9 @@ void cmGlobalXCodeGenerator::CreateCustomCommands(
   }
   // add all the sources
   std::vector<cmCustomCommand> commands;
+  auto& visited = this->CommandsVisited[gtgt];
   for (auto sourceFile : classes) {
-    if (sourceFile->GetCustomCommand()) {
+    if (sourceFile->GetCustomCommand() && visited.insert(sourceFile).second) {
       commands.push_back(*sourceFile->GetCustomCommand());
     }
   }
@@ -1839,6 +1851,15 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
   for (auto const& command : commands) {
     cmCustomCommandGenerator ccg(command, configName,
                                  this->CurrentLocalGenerator);
+    std::vector<std::string> realDepends;
+    realDepends.reserve(ccg.GetDepends().size());
+    for (auto const& d : ccg.GetDepends()) {
+      std::string dep;
+      if (this->CurrentLocalGenerator->GetRealDependency(d, configName, dep)) {
+        realDepends.emplace_back(std::move(dep));
+      }
+    }
+
     if (ccg.GetNumberOfCommands() > 0) {
       makefileStream << "\n";
       const std::vector<std::string>& outputs = ccg.GetOutputs();
@@ -1854,12 +1875,8 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
         // There are no outputs.  Use the generated force rule name.
         makefileStream << tname[&ccg.GetCC()] << ": ";
       }
-      for (auto const& d : ccg.GetDepends()) {
-        std::string dep;
-        if (this->CurrentLocalGenerator->GetRealDependency(d, configName,
-                                                           dep)) {
-          makefileStream << "\\\n" << this->ConvertToRelativeForMake(dep);
-        }
+      for (auto const& dep : realDepends) {
+        makefileStream << "\\\n" << this->ConvertToRelativeForMake(dep);
       }
       makefileStream << "\n";
 
@@ -1888,6 +1905,17 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
         ccg.AppendArguments(c, cmd);
         makefileStream << "\t" << cmd << "\n";
       }
+
+      // Symbolic inputs are not expected to exist, so add dummy rules.
+      for (auto const& dep : realDepends) {
+        if (cmSourceFile* dsf =
+              target->GetLocalGenerator()->GetMakefile()->GetSource(
+                dep, cmSourceFileLocationKind::Known)) {
+          if (dsf->GetPropertyAsBool("SYMBOLIC")) {
+            makefileStream << this->ConvertToRelativeForMake(dep) << ":\n";
+          }
+        }
+      }
     }
   }
 }

+ 2 - 0
Source/cmGlobalXCodeGenerator.h

@@ -306,6 +306,8 @@ private:
   std::string GeneratorToolset;
   std::map<cmGeneratorTarget const*, size_t> TargetOrderIndex;
   std::vector<std::string> EnabledLangs;
+  std::map<cmGeneratorTarget const*, std::set<cmSourceFile const*>>
+    CommandsVisited;
 };
 
 #endif