summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-09-01 18:05:57 (GMT)
committerBrad King <brad.king@kitware.com>2020-09-01 18:05:57 (GMT)
commite33f8f078a289e51636067414ff73d1d1b945552 (patch)
tree741a24742fc8a11f714dca1969f0827f5a592d13 /Source
parent8c60c49ae2ac24915931708435f632e66b713f4b (diff)
downloadCMake-e33f8f078a289e51636067414ff73d1d1b945552.zip
CMake-e33f8f078a289e51636067414ff73d1d1b945552.tar.gz
CMake-e33f8f078a289e51636067414ff73d1d1b945552.tar.bz2
Xcode: Avoid unnecessary duplication of custom commands across targets
Do not attach a custom command to a target if it is already attached to one of the target's dependencies. The command's output will be available by the time the target needs it because the dependency containing the command will have already been built. Since commit fb45559e09 (Xcode: Process targets in depth-first order during generation, 2018-07-19, v3.13.0-rc1~293^2) we generate a target only after generating its dependencies. Therefore when visiting the custom commands in a target, we can assume that custom commands in its dependencies have already been visited.
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx25
-rw-r--r--Source/cmGlobalXCodeGenerator.h2
2 files changed, 26 insertions, 1 deletions
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index c6edfad..450b2b1 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/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());
}
}
@@ -1893,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";
+ }
+ }
+ }
}
}
}
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index f9b6300..c02cc1d 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/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