summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBen Boeckel <ben.boeckel@kitware.com>2017-04-17 20:24:44 (GMT)
committerBen Boeckel <ben.boeckel@kitware.com>2017-04-21 12:57:40 (GMT)
commitadf60b28384025d5b83c2df5a66f2190753e2695 (patch)
treec07e71eca348da7d33108042e6a897efba77166b /Source
parent01c5bb9551ff0322f2cb4d5439a2ab9a94c87815 (diff)
downloadCMake-adf60b28384025d5b83c2df5a66f2190753e2695.zip
CMake-adf60b28384025d5b83c2df5a66f2190753e2695.tar.gz
CMake-adf60b28384025d5b83c2df5a66f2190753e2695.tar.bz2
ninja: break unnecessary target dependencies
Previously, given two libraries, X and Y where X depends on Y, all object compilations of X would require the Y library to have been linked before being compiled. This is not necessary and can instead be loosened such that object compilations of X only depend on the order-only dependencies of Y to be completed. This is to ensure that generated sources, headers, custom commands, etc. are completed before X starts to compile its objects. This should help build performance in projects with many libraries which cause a deep library dependency chain. Previously, a library at the bottom would not start compilation until after all other libraries completed, but now only its link step needs to wait and its compilation jobs can be run in parallel with other tasks. Fixes: #15555
Diffstat (limited to 'Source')
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx29
-rw-r--r--Source/cmGlobalNinjaGenerator.h10
-rw-r--r--Source/cmLocalNinjaGenerator.cxx6
-rw-r--r--Source/cmLocalNinjaGenerator.h4
-rw-r--r--Source/cmNinjaTargetGenerator.cxx18
-rw-r--r--Source/cmNinjaTargetGenerator.h3
-rw-r--r--Source/cmNinjaTypes.h6
7 files changed, 52 insertions, 24 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index e61cbd9..1a77d7c 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -966,8 +966,14 @@ void cmGlobalNinjaGenerator::WriteAssumedSourceDependencies()
}
}
+std::string OrderDependsTargetForTarget(cmGeneratorTarget const* target)
+{
+ return "cmake_object_order_depends_target_" + target->GetName();
+}
+
void cmGlobalNinjaGenerator::AppendTargetOutputs(
- cmGeneratorTarget const* target, cmNinjaDeps& outputs)
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends)
{
std::string configName =
target->Target->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
@@ -979,15 +985,27 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
bool realname = target->IsFrameworkOnApple();
switch (target->GetType()) {
- case cmStateEnums::EXECUTABLE:
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::MODULE_LIBRARY: {
+ if (depends == DependOnTargetOrdering) {
+ outputs.push_back(OrderDependsTargetForTarget(target));
+ break;
+ }
+ }
+ // FALLTHROUGH
+ case cmStateEnums::EXECUTABLE: {
outputs.push_back(this->ConvertToNinjaPath(target->GetFullPath(
configName, cmStateEnums::RuntimeBinaryArtifact, realname)));
break;
}
- case cmStateEnums::OBJECT_LIBRARY:
+ case cmStateEnums::OBJECT_LIBRARY: {
+ if (depends == DependOnTargetOrdering) {
+ outputs.push_back(OrderDependsTargetForTarget(target));
+ break;
+ }
+ }
+ // FALLTHROUGH
case cmStateEnums::GLOBAL_TARGET:
case cmStateEnums::UTILITY: {
std::string path =
@@ -1003,7 +1021,8 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
}
void cmGlobalNinjaGenerator::AppendTargetDepends(
- cmGeneratorTarget const* target, cmNinjaDeps& outputs)
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends)
{
if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
// These depend only on other CMake-provided targets, e.g. "all".
@@ -1023,7 +1042,7 @@ void cmGlobalNinjaGenerator::AppendTargetDepends(
if ((*i)->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
continue;
}
- this->AppendTargetOutputs(*i, outs);
+ this->AppendTargetOutputs(*i, outs, depends);
}
std::sort(outs.begin(), outs.end());
outputs.insert(outputs.end(), outs.begin(), outs.end());
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index e06afb0..b1d6155 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -316,10 +316,12 @@ public:
ASD.insert(deps.begin(), deps.end());
}
- void AppendTargetOutputs(cmGeneratorTarget const* target,
- cmNinjaDeps& outputs);
- void AppendTargetDepends(cmGeneratorTarget const* target,
- cmNinjaDeps& outputs);
+ void AppendTargetOutputs(
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends = DependOnTargetArtifact);
+ void AppendTargetDepends(
+ cmGeneratorTarget const* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AppendTargetDependsClosure(cmGeneratorTarget const* target,
cmNinjaDeps& outputs);
void AddDependencyToAll(cmGeneratorTarget* target);
diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx
index c2d9d57..9d88e35 100644
--- a/Source/cmLocalNinjaGenerator.cxx
+++ b/Source/cmLocalNinjaGenerator.cxx
@@ -278,9 +278,11 @@ void cmLocalNinjaGenerator::AppendTargetOutputs(cmGeneratorTarget* target,
}
void cmLocalNinjaGenerator::AppendTargetDepends(cmGeneratorTarget* target,
- cmNinjaDeps& outputs)
+ cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends)
{
- this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs);
+ this->GetGlobalNinjaGenerator()->AppendTargetDepends(target, outputs,
+ depends);
}
void cmLocalNinjaGenerator::AppendCustomCommandDeps(
diff --git a/Source/cmLocalNinjaGenerator.h b/Source/cmLocalNinjaGenerator.h
index fda4578..a45e018 100644
--- a/Source/cmLocalNinjaGenerator.h
+++ b/Source/cmLocalNinjaGenerator.h
@@ -63,7 +63,9 @@ public:
std::string BuildCommandLine(const std::vector<std::string>& cmdLines);
void AppendTargetOutputs(cmGeneratorTarget* target, cmNinjaDeps& outputs);
- void AppendTargetDepends(cmGeneratorTarget* target, cmNinjaDeps& outputs);
+ void AppendTargetDepends(
+ cmGeneratorTarget* target, cmNinjaDeps& outputs,
+ cmNinjaTargetDepends depends = DependOnTargetArtifact);
void AddCustomCommandTarget(cmCustomCommand const* cc,
cmGeneratorTarget* target);
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index daad3fc..2c14a3e 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -715,8 +715,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
}
cmNinjaDeps orderOnlyDeps;
- this->GetLocalGenerator()->AppendTargetDepends(this->GeneratorTarget,
- orderOnlyDeps);
+ this->GetLocalGenerator()->AppendTargetDepends(
+ this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering);
// Add order-only dependencies on other files associated with the target.
orderOnlyDeps.insert(orderOnlyDeps.end(), this->ExtraFiles.begin(),
@@ -741,7 +741,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
orderOnlyDeps.erase(std::unique(orderOnlyDeps.begin(), orderOnlyDeps.end()),
orderOnlyDeps.end());
- if (!orderOnlyDeps.empty()) {
+ {
cmNinjaDeps orderOnlyTarget;
orderOnlyTarget.push_back(this->OrderDependsTargetForTarget());
this->GetGlobalGenerator()->WritePhonyBuild(
@@ -754,7 +754,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
for (std::vector<cmSourceFile const*>::const_iterator si =
objectSources.begin();
si != objectSources.end(); ++si) {
- this->WriteObjectBuildStatement(*si, !orderOnlyDeps.empty());
+ this->WriteObjectBuildStatement(*si);
}
if (!this->DDIFiles.empty()) {
@@ -779,8 +779,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
// our dependencies produces them. Fixing this will require
// refactoring the Ninja generator to generate targets in
// dependency order so that we can collect the needed information.
- this->GetLocalGenerator()->AppendTargetDepends(this->GeneratorTarget,
- ddOrderOnlyDeps);
+ this->GetLocalGenerator()->AppendTargetDepends(
+ this->GeneratorTarget, ddOrderOnlyDeps, DependOnTargetArtifact);
this->GetGlobalGenerator()->WriteBuild(
this->GetBuildFileStream(), ddComment, ddRule, ddOutputs, ddImplicitOuts,
@@ -791,7 +791,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements()
}
void cmNinjaTargetGenerator::WriteObjectBuildStatement(
- cmSourceFile const* source, bool writeOrderDependsTargetForTarget)
+ cmSourceFile const* source)
{
std::string const language = source->GetLanguage();
std::string const sourceFileName =
@@ -842,9 +842,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
cmNinjaDeps orderOnlyDeps;
- if (writeOrderDependsTargetForTarget) {
- orderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
- }
+ orderOnlyDeps.push_back(this->OrderDependsTargetForTarget());
// If the source file is GENERATED and does not have a custom command
// (either attached to this source file or another one), assume that one of
diff --git a/Source/cmNinjaTargetGenerator.h b/Source/cmNinjaTargetGenerator.h
index 9ce8651..5eb7a9a 100644
--- a/Source/cmNinjaTargetGenerator.h
+++ b/Source/cmNinjaTargetGenerator.h
@@ -119,8 +119,7 @@ protected:
void WriteLanguageRules(const std::string& language);
void WriteCompileRule(const std::string& language);
void WriteObjectBuildStatements();
- void WriteObjectBuildStatement(cmSourceFile const* source,
- bool writeOrderDependsTargetForTarget);
+ void WriteObjectBuildStatement(cmSourceFile const* source);
void WriteTargetDependInfo(std::string const& lang);
void ExportObjectCompileCommand(
diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h
index b4af70e..ec435d9 100644
--- a/Source/cmNinjaTypes.h
+++ b/Source/cmNinjaTypes.h
@@ -9,6 +9,12 @@
#include <string>
#include <vector>
+enum cmNinjaTargetDepends
+{
+ DependOnTargetArtifact,
+ DependOnTargetOrdering
+};
+
typedef std::vector<std::string> cmNinjaDeps;
typedef std::map<std::string, std::string> cmNinjaVars;