From 1b16d7656733a89d1d9735cf31654824b76aab9b Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 11:08:56 +0200 Subject: Ninja: Add cmNinjaBuild utility class --- Source/cmNinjaTypes.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/Source/cmNinjaTypes.h b/Source/cmNinjaTypes.h index 78f3917..52c05b6 100644 --- a/Source/cmNinjaTypes.h +++ b/Source/cmNinjaTypes.h @@ -41,4 +41,24 @@ public: bool Generator = false; }; +class cmNinjaBuild +{ +public: + cmNinjaBuild() = default; + cmNinjaBuild(std::string rule) + : Rule(std::move(rule)) + { + } + + std::string Comment; + std::string Rule; + cmNinjaDeps Outputs; + cmNinjaDeps ImplicitOuts; + cmNinjaDeps ExplicitDeps; + cmNinjaDeps ImplicitDeps; + cmNinjaDeps OrderOnlyDeps; + cmNinjaVars Variables; + std::string RspFile; +}; + #endif // ! cmNinjaTypes_h -- cgit v0.12 From 15c644437ae355ac196cfcfe1e874d8280451b43 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 11:15:07 +0200 Subject: Ninja: Add cmNinjaBuild based WriteBuild (wrapper) method --- Source/cmGlobalNinjaGenerator.cxx | 10 ++++++++++ Source/cmGlobalNinjaGenerator.h | 7 +++++++ 2 files changed, 17 insertions(+) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 3fce29e..c362dc6 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -226,6 +226,16 @@ void cmGlobalNinjaGenerator::WriteBuild( os << buildstr << arguments << assignments; } +void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, + cmNinjaBuild const& build, + int cmdLineLimit, + bool* usedResponseFile) +{ + WriteBuild(os, build.Comment, build.Rule, build.Outputs, build.ImplicitOuts, + build.ExplicitDeps, build.ImplicitDeps, build.OrderOnlyDeps, + build.Variables, build.RspFile, cmdLineLimit, usedResponseFile); +} + void cmGlobalNinjaGenerator::WritePhonyBuild( std::ostream& os, const std::string& comment, const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index dcc358b..037c20e 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -117,6 +117,13 @@ public: int cmdLineLimit = 0, bool* usedResponseFile = nullptr); /** + * Write a build statement @a build to @a os. + * @warning no escaping of any kind is done here. + */ + void WriteBuild(std::ostream& os, cmNinjaBuild const& build, + int cmdLineLimit = 0, bool* usedResponseFile = nullptr); + + /** * Helper to write a build statement with the special 'phony' rule. */ void WritePhonyBuild(std::ostream& os, const std::string& comment, -- cgit v0.12 From 8a46a07c8bd2fddde5e4db797279e21a5575e213 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 11:20:20 +0200 Subject: Ninja: Make WriteMacOSXContentBuild use cmNinjaBuild internally --- Source/cmGlobalNinjaGenerator.cxx | 20 ++++++++------------ Source/cmGlobalNinjaGenerator.h | 4 ++-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index c362dc6..94c7659 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -307,20 +307,16 @@ void cmGlobalNinjaGenerator::AddMacOSXContentRule() this->AddRule(rule); } -void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, - const std::string& output) +void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(std::string input, + std::string output) { this->AddMacOSXContentRule(); - - cmNinjaDeps outputs; - outputs.push_back(output); - cmNinjaDeps deps; - deps.push_back(input); - cmNinjaVars vars; - - this->WriteBuild(*this->BuildFileStream, "", "COPY_OSX_CONTENT", outputs, - /*implicitOuts=*/cmNinjaDeps(), deps, cmNinjaDeps(), - cmNinjaDeps(), cmNinjaVars()); + { + cmNinjaBuild build("COPY_OSX_CONTENT"); + build.Outputs.push_back(std::move(output)); + build.ExplicitDeps.push_back(std::move(input)); + this->WriteBuild(*this->BuildFileStream, build); + } } void cmGlobalNinjaGenerator::WriteRule(std::ostream& os, diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 037c20e..7b62e38 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -141,8 +141,8 @@ public: bool restat, const cmNinjaDeps& outputs, const cmNinjaDeps& deps = cmNinjaDeps(), const cmNinjaDeps& orderOnly = cmNinjaDeps()); - void WriteMacOSXContentBuild(const std::string& input, - const std::string& output); + + void WriteMacOSXContentBuild(std::string input, std::string output); /** * Write a rule statement to @a os. -- cgit v0.12 From 846b4b1062cc83b420ad1405fd74186c33bb1513 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 16:56:22 +0200 Subject: Ninja: Make WriteCustomCommandBuild method use cmNinjaBuild internally --- Source/cmGlobalNinjaGenerator.cxx | 59 ++++++++++++++++++++++----------------- Source/cmGlobalNinjaGenerator.h | 15 +++++----- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 94c7659..ef06ebe 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -259,40 +259,47 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( const std::string& command, const std::string& description, const std::string& comment, const std::string& depfile, const std::string& job_pool, bool uses_terminal, bool restat, - const cmNinjaDeps& outputs, const cmNinjaDeps& deps, - const cmNinjaDeps& orderOnly) + const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps, + const cmNinjaDeps& orderOnlyDeps) { - std::string cmd = command; // NOLINT(*) -#ifdef _WIN32 - if (cmd.empty()) - // TODO Shouldn't an empty command be handled by ninja? - cmd = "cmd.exe /c"; -#endif - this->AddCustomCommandRule(); - cmNinjaVars vars; - vars["COMMAND"] = cmd; - vars["DESC"] = EncodeLiteral(description); - if (restat) { - vars["restat"] = "1"; - } - if (uses_terminal && SupportsConsolePool()) { - vars["pool"] = "console"; - } else if (!job_pool.empty()) { - vars["pool"] = job_pool; - } - if (!depfile.empty()) { - vars["depfile"] = depfile; + { + cmNinjaBuild build("CUSTOM_COMMAND"); + build.Comment = comment; + build.Outputs = outputs; + build.ExplicitDeps = explicitDeps; + build.OrderOnlyDeps = orderOnlyDeps; + + cmNinjaVars& vars = build.Variables; + { + std::string cmd = command; // NOLINT(*) +#ifdef _WIN32 + if (cmd.empty()) + // TODO Shouldn't an empty command be handled by ninja? + cmd = "cmd.exe /c"; +#endif + vars["COMMAND"] = std::move(cmd); + } + vars["DESC"] = EncodeLiteral(description); + if (restat) { + vars["restat"] = "1"; + } + if (uses_terminal && SupportsConsolePool()) { + vars["pool"] = "console"; + } else if (!job_pool.empty()) { + vars["pool"] = job_pool; + } + if (!depfile.empty()) { + vars["depfile"] = depfile; + } + this->WriteBuild(*this->BuildFileStream, build); } - this->WriteBuild(*this->BuildFileStream, comment, "CUSTOM_COMMAND", outputs, - /*implicitOuts=*/cmNinjaDeps(), deps, cmNinjaDeps(), - orderOnly, vars); if (this->ComputingUnknownDependencies) { // we need to track every dependency that comes in, since we are trying // to find dependencies that are side effects of build commands - for (std::string const& dep : deps) { + for (std::string const& dep : explicitDeps) { this->CombinedCustomCommandExplicitDependencies.insert(dep); } } diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 7b62e38..ffd00b5 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -133,14 +133,13 @@ public: const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(), const cmNinjaVars& variables = cmNinjaVars()); - void WriteCustomCommandBuild(const std::string& command, - const std::string& description, - const std::string& comment, - const std::string& depfile, - const std::string& pool, bool uses_terminal, - bool restat, const cmNinjaDeps& outputs, - const cmNinjaDeps& deps = cmNinjaDeps(), - const cmNinjaDeps& orderOnly = cmNinjaDeps()); + void WriteCustomCommandBuild( + const std::string& command, const std::string& description, + const std::string& comment, const std::string& depfile, + const std::string& pool, bool uses_terminal, bool restat, + const cmNinjaDeps& outputs, + const cmNinjaDeps& explicitDeps = cmNinjaDeps(), + const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps()); void WriteMacOSXContentBuild(std::string input, std::string output); -- cgit v0.12 From b6dc977ff17b451b43d8a67584400c3b53c7eb8f Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 12:06:25 +0200 Subject: Ninja: Embrace temporary objects in scopes --- Source/cmNinjaTargetGenerator.cxx | 145 +++++++++++++++++++++----------------- 1 file changed, 80 insertions(+), 65 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 5b8ed90..140730b 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -796,78 +796,93 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() const std::string& config = this->Makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"); - std::vector customCommands; - this->GeneratorTarget->GetCustomCommands(customCommands, config); - for (cmSourceFile const* sf : customCommands) { - cmCustomCommand const* cc = sf->GetCustomCommand(); - this->GetLocalGenerator()->AddCustomCommandTarget( - cc, this->GetGeneratorTarget()); - // Record the custom commands for this target. The container is used - // in WriteObjectBuildStatement when called in a loop below. - this->CustomCommands.push_back(cc); + { + std::vector customCommands; + this->GeneratorTarget->GetCustomCommands(customCommands, config); + for (cmSourceFile const* sf : customCommands) { + cmCustomCommand const* cc = sf->GetCustomCommand(); + this->GetLocalGenerator()->AddCustomCommandTarget( + cc, this->GetGeneratorTarget()); + // Record the custom commands for this target. The container is used + // in WriteObjectBuildStatement when called in a loop below. + this->CustomCommands.push_back(cc); + } } - std::vector headerSources; - this->GeneratorTarget->GetHeaderSources(headerSources, config); - this->OSXBundleGenerator->GenerateMacOSXContentStatements( - headerSources, this->MacOSXContentGenerator.get()); - std::vector extraSources; - this->GeneratorTarget->GetExtraSources(extraSources, config); - this->OSXBundleGenerator->GenerateMacOSXContentStatements( - extraSources, this->MacOSXContentGenerator.get()); - std::vector externalObjects; - this->GeneratorTarget->GetExternalObjects(externalObjects, config); - for (cmSourceFile const* sf : externalObjects) { - this->Objects.push_back(this->GetSourceFilePath(sf)); + { + std::vector headerSources; + this->GeneratorTarget->GetHeaderSources(headerSources, config); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + headerSources, this->MacOSXContentGenerator.get()); } - - cmNinjaDeps orderOnlyDeps; - this->GetLocalGenerator()->AppendTargetDepends( - this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering); - - // Add order-only dependencies on other files associated with the target. - cmAppend(orderOnlyDeps, this->ExtraFiles); - - // Add order-only dependencies on custom command outputs. - for (cmCustomCommand const* cc : this->CustomCommands) { - cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), - this->GetLocalGenerator()); - const std::vector& ccoutputs = ccg.GetOutputs(); - const std::vector& ccbyproducts = ccg.GetByproducts(); - std::transform(ccoutputs.begin(), ccoutputs.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); - std::transform(ccbyproducts.begin(), ccbyproducts.end(), - std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + { + std::vector extraSources; + this->GeneratorTarget->GetExtraSources(extraSources, config); + this->OSXBundleGenerator->GenerateMacOSXContentStatements( + extraSources, this->MacOSXContentGenerator.get()); } - - std::sort(orderOnlyDeps.begin(), orderOnlyDeps.end()); - orderOnlyDeps.erase(std::unique(orderOnlyDeps.begin(), orderOnlyDeps.end()), - orderOnlyDeps.end()); - - // The phony target must depend on at least one input or ninja will explain - // that "output ... of phony edge with no inputs doesn't exist" and consider - // the phony output "dirty". - if (orderOnlyDeps.empty()) { - // Any path that always exists will work here. It would be nice to - // use just "." but that is not supported by Ninja < 1.7. - std::string tgtDir; - tgtDir += this->LocalGenerator->GetCurrentBinaryDirectory(); - tgtDir += "/"; - tgtDir += this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); - orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir)); + { + std::vector externalObjects; + this->GeneratorTarget->GetExternalObjects(externalObjects, config); + for (cmSourceFile const* sf : externalObjects) { + this->Objects.push_back(this->GetSourceFilePath(sf)); + } } { - cmNinjaDeps orderOnlyTarget; - orderOnlyTarget.push_back(this->OrderDependsTargetForTarget()); - this->GetGlobalGenerator()->WritePhonyBuild( - this->GetBuildFileStream(), - "Order-only phony target for " + this->GetTargetName(), orderOnlyTarget, - cmNinjaDeps(), cmNinjaDeps(), orderOnlyDeps); + cmNinjaDeps orderOnlyDeps; + this->GetLocalGenerator()->AppendTargetDepends( + this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering); + + // Add order-only dependencies on other files associated with the target. + cmAppend(orderOnlyDeps, this->ExtraFiles); + + // Add order-only dependencies on custom command outputs. + for (cmCustomCommand const* cc : this->CustomCommands) { + cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), + this->GetLocalGenerator()); + const std::vector& ccoutputs = ccg.GetOutputs(); + const std::vector& ccbyproducts = ccg.GetByproducts(); + std::transform(ccoutputs.begin(), ccoutputs.end(), + std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + std::transform(ccbyproducts.begin(), ccbyproducts.end(), + std::back_inserter(orderOnlyDeps), MapToNinjaPath()); + } + + std::sort(orderOnlyDeps.begin(), orderOnlyDeps.end()); + orderOnlyDeps.erase( + std::unique(orderOnlyDeps.begin(), orderOnlyDeps.end()), + orderOnlyDeps.end()); + + // The phony target must depend on at least one input or ninja will explain + // that "output ... of phony edge with no inputs doesn't exist" and + // consider the phony output "dirty". + if (orderOnlyDeps.empty()) { + // Any path that always exists will work here. It would be nice to + // use just "." but that is not supported by Ninja < 1.7. + std::string tgtDir; + tgtDir += this->LocalGenerator->GetCurrentBinaryDirectory(); + tgtDir += "/"; + tgtDir += + this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget); + orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir)); + } + + { + cmNinjaDeps orderOnlyTarget; + orderOnlyTarget.push_back(this->OrderDependsTargetForTarget()); + this->GetGlobalGenerator()->WritePhonyBuild( + this->GetBuildFileStream(), + "Order-only phony target for " + this->GetTargetName(), + orderOnlyTarget, cmNinjaDeps(), cmNinjaDeps(), orderOnlyDeps); + } } - std::vector objectSources; - this->GeneratorTarget->GetObjectSources(objectSources, config); - for (cmSourceFile const* sf : objectSources) { - this->WriteObjectBuildStatement(sf); + + { + std::vector objectSources; + this->GeneratorTarget->GetObjectSources(objectSources, config); + for (cmSourceFile const* sf : objectSources) { + this->WriteObjectBuildStatement(sf); + } } for (auto const& langDDIFiles : this->DDIFiles) { -- cgit v0.12 From 0eed548d3f0387a3bcbdc42ad4456987a37b2934 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 12:19:00 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmNinjaTargetGenerator.cxx | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 140730b..e878adb 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -829,7 +829,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() } { - cmNinjaDeps orderOnlyDeps; + cmNinjaBuild build("phony"); + build.Comment = "Order-only phony target for " + this->GetTargetName(); + build.Outputs.push_back(this->OrderDependsTargetForTarget()); + + cmNinjaDeps& orderOnlyDeps = build.OrderOnlyDeps; this->GetLocalGenerator()->AppendTargetDepends( this->GeneratorTarget, orderOnlyDeps, DependOnTargetOrdering); @@ -867,14 +871,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() orderOnlyDeps.push_back(this->ConvertToNinjaPath(tgtDir)); } - { - cmNinjaDeps orderOnlyTarget; - orderOnlyTarget.push_back(this->OrderDependsTargetForTarget()); - this->GetGlobalGenerator()->WritePhonyBuild( - this->GetBuildFileStream(), - "Order-only phony target for " + this->GetTargetName(), - orderOnlyTarget, cmNinjaDeps(), cmNinjaDeps(), orderOnlyDeps); - } + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build); } { -- cgit v0.12 From df72f06182f3481fe8929c49578052748d980712 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 15:11:52 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmNinjaTargetGenerator.cxx | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index e878adb..8eb9dbd 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -1164,13 +1164,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { - std::vector outputList; - cmSystemTools::ExpandListArgument(objectOutputs, outputList); - std::transform(outputList.begin(), outputList.end(), outputList.begin(), - MapToNinjaPath()); - this->GetGlobalGenerator()->WritePhonyBuild(this->GetBuildFileStream(), - "Additional output files.", - outputList, outputs); + cmNinjaBuild build("phony"); + build.Comment = "Additional output files."; + build.Outputs = cmSystemTools::ExpandedListArgument(objectOutputs); + std::transform(build.Outputs.begin(), build.Outputs.end(), + build.Outputs.begin(), MapToNinjaPath()); + build.ExplicitDeps = std::move(outputs); + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build); } } -- cgit v0.12 From dff42d481230599ba7962a5895d75e7c0d16939e Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 11:52:22 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmNinjaNormalTargetGenerator.cxx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 6e9e112..2e410c8 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -1123,13 +1123,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() void cmNinjaNormalTargetGenerator::WriteObjectLibStatement() { // Write a phony output that depends on all object files. - cmNinjaDeps outputs; - this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(), - outputs); - cmNinjaDeps depends = this->GetObjects(); - this->GetGlobalGenerator()->WritePhonyBuild( - this->GetBuildFileStream(), "Object library " + this->GetTargetName(), - outputs, depends); + { + cmNinjaBuild build("phony"); + build.Comment = "Object library " + this->GetTargetName(); + this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(), + build.Outputs); + build.ExplicitDeps = this->GetObjects(); + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build); + } // Add aliases for the target name. this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), -- cgit v0.12 From 09c21914b320567583ce5ff4c92e56b8a54bf3cb Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 12:25:12 +0200 Subject: Ninja: Embrace temporary objects in scopes --- Source/cmNinjaUtilityTargetGenerator.cxx | 130 +++++++++++++++---------------- 1 file changed, 61 insertions(+), 69 deletions(-) diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index ab777c8..9d05110 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -16,6 +16,7 @@ #include "cmSystemTools.h" #include +#include #include #include #include @@ -30,8 +31,11 @@ cmNinjaUtilityTargetGenerator::~cmNinjaUtilityTargetGenerator() = default; void cmNinjaUtilityTargetGenerator::Generate() { - std::string utilCommandName = - this->GetLocalGenerator()->GetCurrentBinaryDirectory(); + cmGlobalNinjaGenerator* gg = this->GetGlobalGenerator(); + cmLocalNinjaGenerator* lg = this->GetLocalGenerator(); + cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); + + std::string utilCommandName = lg->GetCurrentBinaryDirectory(); utilCommandName += "/CMakeFiles"; utilCommandName += "/"; utilCommandName += this->GetTargetName() + ".util"; @@ -40,64 +44,60 @@ void cmNinjaUtilityTargetGenerator::Generate() std::vector commands; cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName); - const std::vector* cmdLists[2] = { - &this->GetGeneratorTarget()->GetPreBuildCommands(), - &this->GetGeneratorTarget()->GetPostBuildCommands() - }; - bool uses_terminal = false; - - for (unsigned i = 0; i != 2; ++i) { - for (cmCustomCommand const& ci : *cmdLists[i]) { - cmCustomCommandGenerator ccg(ci, this->GetConfigName(), - this->GetLocalGenerator()); - this->GetLocalGenerator()->AppendCustomCommandDeps(ccg, deps); - this->GetLocalGenerator()->AppendCustomCommandLines(ccg, commands); - std::vector const& ccByproducts = ccg.GetByproducts(); - std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(util_outputs), MapToNinjaPath()); - if (ci.GetUsesTerminal()) { - uses_terminal = true; + { + std::array const*, 2> const cmdLists = { + { &genTarget->GetPreBuildCommands(), &genTarget->GetPostBuildCommands() } + }; + + for (std::vector const* cmdList : cmdLists) { + for (cmCustomCommand const& ci : *cmdList) { + cmCustomCommandGenerator ccg(ci, this->GetConfigName(), lg); + lg->AppendCustomCommandDeps(ccg, deps); + lg->AppendCustomCommandLines(ccg, commands); + std::vector const& ccByproducts = ccg.GetByproducts(); + std::transform(ccByproducts.begin(), ccByproducts.end(), + std::back_inserter(util_outputs), MapToNinjaPath()); + if (ci.GetUsesTerminal()) { + uses_terminal = true; + } } } } - std::vector sources; - std::string config = - this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"); - this->GetGeneratorTarget()->GetSourceFiles(sources, config); - for (cmSourceFile const* source : sources) { - if (cmCustomCommand const* cc = source->GetCustomCommand()) { - cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), - this->GetLocalGenerator()); - this->GetLocalGenerator()->AddCustomCommandTarget( - cc, this->GetGeneratorTarget()); - - // Depend on all custom command outputs. - const std::vector& ccOutputs = ccg.GetOutputs(); - const std::vector& ccByproducts = ccg.GetByproducts(); - std::transform(ccOutputs.begin(), ccOutputs.end(), - std::back_inserter(deps), MapToNinjaPath()); - std::transform(ccByproducts.begin(), ccByproducts.end(), - std::back_inserter(deps), MapToNinjaPath()); + { + std::string const& config = + this->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE"); + std::vector sources; + genTarget->GetSourceFiles(sources, config); + for (cmSourceFile const* source : sources) { + if (cmCustomCommand const* cc = source->GetCustomCommand()) { + cmCustomCommandGenerator ccg(*cc, this->GetConfigName(), lg); + lg->AddCustomCommandTarget(cc, genTarget); + + // Depend on all custom command outputs. + const std::vector& ccOutputs = ccg.GetOutputs(); + const std::vector& ccByproducts = ccg.GetByproducts(); + std::transform(ccOutputs.begin(), ccOutputs.end(), + std::back_inserter(deps), MapToNinjaPath()); + std::transform(ccByproducts.begin(), ccByproducts.end(), + std::back_inserter(deps), MapToNinjaPath()); + } } } - this->GetLocalGenerator()->AppendTargetOutputs(this->GetGeneratorTarget(), - outputs); - this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(), - deps); + lg->AppendTargetOutputs(genTarget, outputs); + lg->AppendTargetDepends(genTarget, deps); if (commands.empty()) { - this->GetGlobalGenerator()->WritePhonyBuild( - this->GetBuildFileStream(), - "Utility command for " + this->GetTargetName(), outputs, deps); + gg->WritePhonyBuild(this->GetBuildFileStream(), + "Utility command for " + this->GetTargetName(), + outputs, deps); } else { - std::string command = this->GetLocalGenerator()->BuildCommandLine( - commands, "utility", this->GeneratorTarget); - const char* echoStr = - this->GetGeneratorTarget()->GetProperty("EchoString"); + std::string command = + lg->BuildCommandLine(commands, "utility", this->GeneratorTarget); std::string desc; + const char* echoStr = genTarget->GetProperty("EchoString"); if (echoStr) { desc = echoStr; } else { @@ -108,18 +108,12 @@ void cmNinjaUtilityTargetGenerator::Generate() // makefile vars. cmSystemTools::ReplaceString( command, "$(CMAKE_SOURCE_DIR)", - this->GetLocalGenerator() - ->ConvertToOutputFormat( - this->GetLocalGenerator()->GetSourceDirectory(), - cmOutputConverter::SHELL) - .c_str()); + lg->ConvertToOutputFormat(lg->GetSourceDirectory(), + cmOutputConverter::SHELL)); cmSystemTools::ReplaceString( command, "$(CMAKE_BINARY_DIR)", - this->GetLocalGenerator() - ->ConvertToOutputFormat( - this->GetLocalGenerator()->GetBinaryDirectory(), - cmOutputConverter::SHELL) - .c_str()); + lg->ConvertToOutputFormat(lg->GetBinaryDirectory(), + cmOutputConverter::SHELL)); cmSystemTools::ReplaceString(command, "$(ARGS)", ""); if (command.find('$') != std::string::npos) { @@ -127,24 +121,22 @@ void cmNinjaUtilityTargetGenerator::Generate() } for (std::string const& util_output : util_outputs) { - this->GetGlobalGenerator()->SeenCustomCommandOutput(util_output); + gg->SeenCustomCommandOutput(util_output); } - this->GetGlobalGenerator()->WriteCustomCommandBuild( - command, desc, "Utility command for " + this->GetTargetName(), - /*depfile*/ "", /*job_pool*/ "", uses_terminal, - /*restat*/ true, util_outputs, deps); + gg->WriteCustomCommandBuild(command, desc, + "Utility command for " + this->GetTargetName(), + /*depfile*/ "", /*job_pool*/ "", uses_terminal, + /*restat*/ true, util_outputs, deps); - this->GetGlobalGenerator()->WritePhonyBuild( - this->GetBuildFileStream(), "", outputs, - cmNinjaDeps(1, utilCommandName)); + gg->WritePhonyBuild(this->GetBuildFileStream(), "", outputs, + cmNinjaDeps(1, utilCommandName)); } // Add an alias for the logical target name regardless of what directory // contains it. Skip this for GLOBAL_TARGET because they are meant to // be per-directory and have one at the top-level anyway. - if (this->GetGeneratorTarget()->GetType() != cmStateEnums::GLOBAL_TARGET) { - this->GetGlobalGenerator()->AddTargetAlias(this->GetTargetName(), - this->GetGeneratorTarget()); + if (genTarget->GetType() != cmStateEnums::GLOBAL_TARGET) { + gg->AddTargetAlias(this->GetTargetName(), genTarget); } } -- cgit v0.12 From 0d0cb136fb19d96f857f8d7da918e18038d5b627 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 13:23:06 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmNinjaUtilityTargetGenerator.cxx | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Source/cmNinjaUtilityTargetGenerator.cxx b/Source/cmNinjaUtilityTargetGenerator.cxx index 9d05110..1225cbd 100644 --- a/Source/cmNinjaUtilityTargetGenerator.cxx +++ b/Source/cmNinjaUtilityTargetGenerator.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include cmNinjaUtilityTargetGenerator::cmNinjaUtilityTargetGenerator( @@ -41,8 +42,9 @@ void cmNinjaUtilityTargetGenerator::Generate() utilCommandName += this->GetTargetName() + ".util"; utilCommandName = this->ConvertToNinjaPath(utilCommandName); + cmNinjaBuild phonyBuild("phony"); std::vector commands; - cmNinjaDeps deps, outputs, util_outputs(1, utilCommandName); + cmNinjaDeps deps, util_outputs(1, utilCommandName); bool uses_terminal = false; { @@ -86,13 +88,13 @@ void cmNinjaUtilityTargetGenerator::Generate() } } - lg->AppendTargetOutputs(genTarget, outputs); + lg->AppendTargetOutputs(genTarget, phonyBuild.Outputs); lg->AppendTargetDepends(genTarget, deps); if (commands.empty()) { - gg->WritePhonyBuild(this->GetBuildFileStream(), - "Utility command for " + this->GetTargetName(), - outputs, deps); + phonyBuild.Comment = "Utility command for " + this->GetTargetName(); + phonyBuild.ExplicitDeps = std::move(deps); + gg->WriteBuild(this->GetBuildFileStream(), phonyBuild); } else { std::string command = lg->BuildCommandLine(commands, "utility", this->GeneratorTarget); @@ -129,8 +131,8 @@ void cmNinjaUtilityTargetGenerator::Generate() /*depfile*/ "", /*job_pool*/ "", uses_terminal, /*restat*/ true, util_outputs, deps); - gg->WritePhonyBuild(this->GetBuildFileStream(), "", outputs, - cmNinjaDeps(1, utilCommandName)); + phonyBuild.ExplicitDeps.push_back(utilCommandName); + gg->WriteBuild(this->GetBuildFileStream(), phonyBuild); } // Add an alias for the logical target name regardless of what directory -- cgit v0.12 From e762da6dc98474a71d0e69866ec3800af3117466 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 13:40:09 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmLocalNinjaGenerator.cxx | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/Source/cmLocalNinjaGenerator.cxx b/Source/cmLocalNinjaGenerator.cxx index 9b651a4..81cafa3 100644 --- a/Source/cmLocalNinjaGenerator.cxx +++ b/Source/cmLocalNinjaGenerator.cxx @@ -454,7 +454,8 @@ void cmLocalNinjaGenerator::AppendCustomCommandLines( void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( cmCustomCommand const* cc, const cmNinjaDeps& orderOnlyDeps) { - if (this->GetGlobalNinjaGenerator()->SeenCustomCommand(cc)) { + cmGlobalNinjaGenerator* gg = this->GetGlobalNinjaGenerator(); + if (gg->SeenCustomCommand(cc)) { return; } @@ -462,13 +463,12 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( const std::vector& outputs = ccg.GetOutputs(); const std::vector& byproducts = ccg.GetByproducts(); - cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size()), ninjaDeps; bool symbolic = false; for (std::string const& output : outputs) { if (cmSourceFile* sf = this->Makefile->GetSource(output)) { - symbolic = sf->GetPropertyAsBool("SYMBOLIC"); - if (symbolic) { + if (sf->GetPropertyAsBool("SYMBOLIC")) { + symbolic = true; break; } } @@ -479,25 +479,29 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( file of each imported target that has an add_dependencies pointing \ at us. How to know which ExternalProject step actually provides it? #endif + cmNinjaDeps ninjaOutputs(outputs.size() + byproducts.size()); std::transform(outputs.begin(), outputs.end(), ninjaOutputs.begin(), - this->GetGlobalNinjaGenerator()->MapToNinjaPath()); + gg->MapToNinjaPath()); std::transform(byproducts.begin(), byproducts.end(), - ninjaOutputs.begin() + outputs.size(), - this->GetGlobalNinjaGenerator()->MapToNinjaPath()); - this->AppendCustomCommandDeps(ccg, ninjaDeps); + ninjaOutputs.begin() + outputs.size(), gg->MapToNinjaPath()); for (std::string const& ninjaOutput : ninjaOutputs) { - this->GetGlobalNinjaGenerator()->SeenCustomCommandOutput(ninjaOutput); + gg->SeenCustomCommandOutput(ninjaOutput); } + cmNinjaDeps ninjaDeps; + this->AppendCustomCommandDeps(ccg, ninjaDeps); + std::vector cmdLines; this->AppendCustomCommandLines(ccg, cmdLines); if (cmdLines.empty()) { - this->GetGlobalNinjaGenerator()->WritePhonyBuild( - this->GetBuildFileStream(), - "Phony custom command for " + ninjaOutputs[0], ninjaOutputs, ninjaDeps, - cmNinjaDeps(), orderOnlyDeps, cmNinjaVars()); + 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->GetBuildFileStream(), build); } else { std::string customStep = cmSystemTools::GetFilenameName(ninjaOutputs[0]); // Hash full path to make unique. @@ -505,7 +509,7 @@ void cmLocalNinjaGenerator::WriteCustomCommandBuildStatement( cmCryptoHash hash(cmCryptoHash::AlgoSHA256); customStep += hash.HashString(ninjaOutputs[0]).substr(0, 7); - this->GetGlobalNinjaGenerator()->WriteCustomCommandBuild( + gg->WriteCustomCommandBuild( this->BuildCommandLine(cmdLines, customStep), this->ConstructComment(ccg), "Custom command for " + ninjaOutputs[0], cc->GetDepfile(), cc->GetJobPool(), cc->GetUsesTerminal(), -- cgit v0.12 From 43af4ca78e80c65d3c0cf2c5121d61988e9d5192 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 13:46:04 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmGlobalNinjaGenerator.cxx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index ef06ebe..8cfbae3 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1096,6 +1096,8 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Target aliases.\n\n"; + cmNinjaBuild build("phony"); + build.Outputs.emplace_back(""); for (auto const& ta : TargetAliases) { // Don't write ambiguous aliases. if (!ta.second) { @@ -1108,10 +1110,13 @@ void cmGlobalNinjaGenerator::WriteTargetAliases(std::ostream& os) continue; } - cmNinjaDeps deps; - this->AppendTargetOutputs(ta.second, deps); - - this->WritePhonyBuild(os, "", cmNinjaDeps(1, ta.first), deps); + // Outputs + build.Outputs[0] = ta.first; + // Explicit depdendencies + build.ExplicitDeps.clear(); + this->AppendTargetOutputs(ta.second, build.ExplicitDeps); + // Write + this->WriteBuild(os, build); } } -- cgit v0.12 From e97ea5201037b67012ecabb1cb7aebabebfed20d Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 14:21:17 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmGlobalNinjaGenerator.cxx | 46 ++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 8cfbae3..2d84271 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1125,13 +1125,22 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) cmGlobalNinjaGenerator::WriteDivider(os); os << "# Folder targets.\n\n"; + std::string const& rootBinaryDir = + this->LocalGenerators[0]->GetBinaryDirectory(); + std::map targetsPerFolder; for (cmLocalGenerator const* lg : this->LocalGenerators) { - const std::string currentBinaryFolder( + std::string const& currentBinaryFolder( lg->GetStateSnapshot().GetDirectory().GetCurrentBinary()); + + // Do not generate a rule for the root binary dir. + if (currentBinaryFolder == rootBinaryDir) { + continue; + } + // The directory-level rule should depend on the target-level rules // for all targets in the directory. - targetsPerFolder[currentBinaryFolder] = cmNinjaDeps(); + cmNinjaDeps& folderTargets = targetsPerFolder[currentBinaryFolder]; for (auto gt : lg->GetGeneratorTargets()) { cmStateEnums::TargetType const type = gt->GetType(); if ((type == cmStateEnums::EXECUTABLE || @@ -1141,37 +1150,34 @@ void cmGlobalNinjaGenerator::WriteFolderTargets(std::ostream& os) type == cmStateEnums::OBJECT_LIBRARY || type == cmStateEnums::UTILITY) && !gt->GetPropertyAsBool("EXCLUDE_FROM_ALL")) { - targetsPerFolder[currentBinaryFolder].push_back(gt->GetName()); + folderTargets.push_back(gt->GetName()); } } // The directory-level rule should depend on the directory-level // rules of the subdirectories. for (cmStateSnapshot const& state : lg->GetStateSnapshot().GetChildren()) { - std::string const currentBinaryDir = + std::string const& currentBinaryDir = state.GetDirectory().GetCurrentBinary(); - - targetsPerFolder[currentBinaryFolder].push_back( + folderTargets.push_back( this->ConvertToNinjaPath(currentBinaryDir + "/all")); } } - std::string const rootBinaryDir = - this->LocalGenerators[0]->GetBinaryDirectory(); - for (auto const& it : targetsPerFolder) { - cmGlobalNinjaGenerator::WriteDivider(os); - std::string const& currentBinaryDir = it.first; + if (!targetsPerFolder.empty()) { + cmNinjaBuild build("phony"); + build.Outputs.emplace_back(""); + for (auto& it : targetsPerFolder) { + cmGlobalNinjaGenerator::WriteDivider(os); + std::string const& currentBinaryDir = it.first; - // Do not generate a rule for the root binary dir. - if (rootBinaryDir.length() >= currentBinaryDir.length()) { - continue; + // Setup target + build.Comment = "Folder: " + currentBinaryDir; + build.Outputs[0] = this->ConvertToNinjaPath(currentBinaryDir + "/all"); + build.ExplicitDeps = std::move(it.second); + // Write target + this->WriteBuild(os, build); } - - std::string const comment = "Folder: " + currentBinaryDir; - cmNinjaDeps output(1); - output.push_back(this->ConvertToNinjaPath(currentBinaryDir + "/all")); - - this->WritePhonyBuild(os, comment, output, it.second); } } -- cgit v0.12 From 1e7e47f597754e800673b158ce1bd59c8b6c566a Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 14:52:17 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmGlobalNinjaGenerator.cxx | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 2d84271..87a9dac 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1258,23 +1258,26 @@ void cmGlobalNinjaGenerator::WriteUnknownExplicitDependencies(std::ostream& os) knownDependencies.begin(), knownDependencies.end(), std::back_inserter(unknownExplicitDepends)); - std::string const rootBuildDirectory = - this->GetCMakeInstance()->GetHomeOutputDirectory(); - bool const inSourceBuild = - (rootBuildDirectory == this->GetCMakeInstance()->GetHomeDirectory()); std::vector warnExplicitDepends; - for (std::string const& i : unknownExplicitDepends) { - // verify the file is in the build directory - std::string const absDepPath = - cmSystemTools::CollapseFullPath(i, rootBuildDirectory); - bool const inBuildDir = - cmSystemTools::IsSubDirectory(absDepPath, rootBuildDirectory); - if (inBuildDir) { - cmNinjaDeps deps(1, i); - this->WritePhonyBuild(os, "", deps, cmNinjaDeps()); - if (this->PolicyCMP0058 == cmPolicies::WARN && !inSourceBuild && - warnExplicitDepends.size() < 10) { - warnExplicitDepends.push_back(i); + if (!unknownExplicitDepends.empty()) { + cmake* cmk = this->GetCMakeInstance(); + std::string const& buildRoot = cmk->GetHomeOutputDirectory(); + bool const inSource = (buildRoot == cmk->GetHomeDirectory()); + bool const warn = (!inSource && (this->PolicyCMP0058 == cmPolicies::WARN)); + cmNinjaBuild build("phony"); + build.Outputs.emplace_back(""); + for (std::string const& ued : unknownExplicitDepends) { + // verify the file is in the build directory + std::string const absDepPath = + cmSystemTools::CollapseFullPath(ued, buildRoot); + if (cmSystemTools::IsSubDirectory(absDepPath, buildRoot)) { + // Generate phony build statement + build.Outputs[0] = ued; + this->WriteBuild(os, build); + // Add to warning on demand + if (warn && warnExplicitDepends.size() < 10) { + warnExplicitDepends.push_back(ued); + } } } } -- cgit v0.12 From c367f7d5469e21739629a896aea3a04bb476c2bf Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 14:58:18 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmGlobalNinjaGenerator.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 87a9dac..1980261 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1318,14 +1318,14 @@ void cmGlobalNinjaGenerator::WriteBuiltinTargets(std::ostream& os) void cmGlobalNinjaGenerator::WriteTargetAll(std::ostream& os) { - cmNinjaDeps outputs; - outputs.push_back(this->TargetAll); - - this->WritePhonyBuild(os, "The main all target.", outputs, - this->AllDependencies); + cmNinjaBuild build("phony"); + build.Comment = "The main all target."; + build.Outputs.push_back(this->TargetAll); + build.ExplicitDeps = this->AllDependencies; + this->WriteBuild(os, build); if (!this->HasOutputPathPrefix()) { - cmGlobalNinjaGenerator::WriteDefault(os, outputs, + cmGlobalNinjaGenerator::WriteDefault(os, build.Outputs, "Make the all target the default."); } } -- cgit v0.12 From fe018819cb4b944cafbd6d8b9e9f6332014579a9 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 15:03:23 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmGlobalNinjaGenerator.cxx | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 1980261..e3ea489 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1382,11 +1382,10 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) this->WriteRule(*this->RulesFileStream, rule); } - std::string verifyForce = cm->GetGlobVerifyScript() + "_force"; - cmNinjaDeps verifyForceDeps(1, this->NinjaOutputPath(verifyForce)); - - this->WritePhonyBuild(os, "Phony target to force glob verification run.", - verifyForceDeps, cmNinjaDeps()); + cmNinjaBuild phonyBuild("phony"); + phonyBuild.Comment = "Phony target to force glob verification run."; + phonyBuild.Outputs.push_back(cm->GetGlobVerifyScript() + "_force"); + this->WriteBuild(os, phonyBuild); variables["restat"] = "1"; std::string const verifyScriptFile = @@ -1399,7 +1398,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) /*outputs=*/cmNinjaDeps(1, verifyStampFile), /*implicitOuts=*/cmNinjaDeps(), /*explicitDeps=*/cmNinjaDeps(), - /*implicitDeps=*/verifyForceDeps, + /*implicitDeps=*/phonyBuild.Outputs, /*orderOnlyDeps=*/cmNinjaDeps(), variables); variables.erase("restat"); -- cgit v0.12 From 5823510745224f0e9ba6d69313c139bcfd9a3953 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 15:14:19 +0200 Subject: Ninja: Use cmNinjaBuild instead of WritePhonyBuild --- Source/cmGlobalNinjaGenerator.cxx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index e3ea489..c40b571 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1432,14 +1432,16 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, /*orderOnlyDeps=*/cmNinjaDeps(), variables); - cmNinjaDeps missingInputs; - std::set_difference(std::make_move_iterator(implicitDeps.begin()), - std::make_move_iterator(implicitDeps.end()), - CustomCommandOutputs.begin(), CustomCommandOutputs.end(), - std::back_inserter(missingInputs)); - - this->WritePhonyBuild(os, "A missing CMake input file is not an error.", - missingInputs, cmNinjaDeps()); + { + cmNinjaBuild build("phony"); + build.Comment = "A missing CMake input file is not an error."; + std::set_difference(std::make_move_iterator(implicitDeps.begin()), + std::make_move_iterator(implicitDeps.end()), + CustomCommandOutputs.begin(), + CustomCommandOutputs.end(), + std::back_inserter(build.Outputs)); + this->WriteBuild(os, build); + } } std::string cmGlobalNinjaGenerator::CMakeCmd() const -- cgit v0.12 From 2dc483476c134ec6fb05802990a98df406a39caf Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 15:18:43 +0200 Subject: Ninja: Remove WritePhonyBuild method --- Source/cmGlobalNinjaGenerator.cxx | 10 ---------- Source/cmGlobalNinjaGenerator.h | 10 ---------- 2 files changed, 20 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index c40b571..cde764f 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -236,16 +236,6 @@ void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, build.Variables, build.RspFile, cmdLineLimit, usedResponseFile); } -void cmGlobalNinjaGenerator::WritePhonyBuild( - std::ostream& os, const std::string& comment, const cmNinjaDeps& outputs, - const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, - const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables) -{ - this->WriteBuild(os, comment, "phony", outputs, - /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, - orderOnlyDeps, variables); -} - void cmGlobalNinjaGenerator::AddCustomCommandRule() { cmNinjaRule rule("CUSTOM_COMMAND"); diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index ffd00b5..4ccd927 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -123,16 +123,6 @@ public: void WriteBuild(std::ostream& os, cmNinjaBuild const& build, int cmdLineLimit = 0, bool* usedResponseFile = nullptr); - /** - * Helper to write a build statement with the special 'phony' rule. - */ - void WritePhonyBuild(std::ostream& os, const std::string& comment, - const cmNinjaDeps& outputs, - const cmNinjaDeps& explicitDeps, - const cmNinjaDeps& implicitDeps = cmNinjaDeps(), - const cmNinjaDeps& orderOnlyDeps = cmNinjaDeps(), - const cmNinjaVars& variables = cmNinjaVars()); - void WriteCustomCommandBuild( const std::string& command, const std::string& description, const std::string& comment, const std::string& depfile, -- cgit v0.12 From fc451f130ded493ae13fda1950d31acc39002ffc Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 15:41:27 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmNinjaTargetGenerator.cxx | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 8eb9dbd..2bc5765 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -886,19 +886,12 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() std::string const& language = langDDIFiles.first; cmNinjaDeps const& ddiFiles = langDDIFiles.second; - std::string const ddComment; - std::string const ddRule = this->LanguageDyndepRule(language); - cmNinjaDeps ddOutputs; - cmNinjaDeps ddImplicitOuts; - cmNinjaDeps const& ddExplicitDeps = ddiFiles; - cmNinjaDeps ddImplicitDeps; - cmNinjaDeps ddOrderOnlyDeps; - cmNinjaVars ddVars; + cmNinjaBuild build(this->LanguageDyndepRule(language)); + build.Outputs.push_back(this->GetDyndepFilePath(language)); + build.ExplicitDeps = ddiFiles; this->WriteTargetDependInfo(language); - ddOutputs.push_back(this->GetDyndepFilePath(language)); - // Make sure dyndep files for all our dependencies have already // been generated so that the 'Modules.json' files they // produced as side-effects are available for us to read. @@ -908,11 +901,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements() // refactoring the Ninja generator to generate targets in // dependency order so that we can collect the needed information. this->GetLocalGenerator()->AppendTargetDepends( - this->GeneratorTarget, ddOrderOnlyDeps, DependOnTargetArtifact); + this->GeneratorTarget, build.OrderOnlyDeps, DependOnTargetArtifact); - this->GetGlobalGenerator()->WriteBuild( - this->GetBuildFileStream(), ddComment, ddRule, ddOutputs, ddImplicitOuts, - ddExplicitDeps, ddImplicitDeps, ddOrderOnlyDeps, ddVars); + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build); } this->GetBuildFileStream() << "\n"; -- cgit v0.12 From 477f9e309563ec642c7323337e0aaf79a1256dac Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 15:52:10 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmNinjaTargetGenerator.cxx | 60 +++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 2bc5765..47fec28 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -1025,39 +1025,34 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( // For some cases we do an explicit preprocessor invocation. bool const explicitPP = this->NeedExplicitPreprocessing(language); if (explicitPP) { - bool const compilePP = this->UsePreprocessedSource(language); - std::string const ppComment; - std::string const ppRule = this->LanguagePreprocessRule(language); - cmNinjaDeps ppOutputs; - cmNinjaDeps ppImplicitOuts; - cmNinjaDeps ppExplicitDeps; - cmNinjaDeps ppImplicitDeps; - cmNinjaDeps ppOrderOnlyDeps; - cmNinjaVars ppVars; + cmNinjaBuild ppBuild(this->LanguagePreprocessRule(language)); std::string const ppFileName = this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source)); - ppOutputs.push_back(ppFileName); + ppBuild.Outputs.push_back(ppFileName); + + ppBuild.RspFile = ppFileName + ".rsp"; + bool const compilePP = this->UsePreprocessedSource(language); if (compilePP) { // Move compilation dependencies to the preprocessing build statement. - std::swap(ppExplicitDeps, explicitDeps); - std::swap(ppImplicitDeps, implicitDeps); - std::swap(ppOrderOnlyDeps, orderOnlyDeps); - std::swap(ppVars["IN_ABS"], vars["IN_ABS"]); + std::swap(ppBuild.ExplicitDeps, explicitDeps); + std::swap(ppBuild.ImplicitDeps, implicitDeps); + std::swap(ppBuild.OrderOnlyDeps, orderOnlyDeps); + std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]); // The actual compilation will now use the preprocessed source. explicitDeps.push_back(ppFileName); } else { // Copy compilation dependencies to the preprocessing build statement. - ppExplicitDeps = explicitDeps; - ppImplicitDeps = implicitDeps; - ppOrderOnlyDeps = orderOnlyDeps; - ppVars["IN_ABS"] = vars["IN_ABS"]; + ppBuild.ExplicitDeps = explicitDeps; + ppBuild.ImplicitDeps = implicitDeps; + ppBuild.OrderOnlyDeps = orderOnlyDeps; + ppBuild.Variables["IN_ABS"] = vars["IN_ABS"]; } // Preprocessing and compilation generally use the same flags. - ppVars["FLAGS"] = vars["FLAGS"]; + ppBuild.Variables["FLAGS"] = vars["FLAGS"]; if (compilePP) { // In case compilation requires flags that are incompatible with @@ -1069,16 +1064,16 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( if (compilePP) { // Move preprocessor definitions to the preprocessor build statement. - std::swap(ppVars["DEFINES"], vars["DEFINES"]); + std::swap(ppBuild.Variables["DEFINES"], vars["DEFINES"]); } else { // Copy preprocessor definitions to the preprocessor build statement. - ppVars["DEFINES"] = vars["DEFINES"]; + ppBuild.Variables["DEFINES"] = vars["DEFINES"]; } // Copy include directories to the preprocessor build statement. The // Fortran compilation build statement still needs them for the INCLUDE // directive. - ppVars["INCLUDES"] = vars["INCLUDES"]; + ppBuild.Variables["INCLUDES"] = vars["INCLUDES"]; if (compilePP) { // Prepend source file's original directory as an include directory @@ -1095,8 +1090,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } // Explicit preprocessing always uses a depfile. - ppVars["DEP_FILE"] = this->GetLocalGenerator()->ConvertToOutputFormat( - objectFileName + ".pp.d", cmOutputConverter::SHELL); + ppBuild.Variables["DEP_FILE"] = + this->GetLocalGenerator()->ConvertToOutputFormat( + objectFileName + ".pp.d", cmOutputConverter::SHELL); if (compilePP) { // The actual compilation does not need a depfile because it // depends on the already-preprocessed source. @@ -1106,24 +1102,20 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( if (needDyndep) { // Tell dependency scanner the object file that will result from // compiling the source. - ppVars["OBJ_FILE"] = objectFileName; + ppBuild.Variables["OBJ_FILE"] = objectFileName; // Tell dependency scanner where to store dyndep intermediate results. std::string const ddiFile = objectFileName + ".ddi"; - ppVars["DYNDEP_INTERMEDIATE_FILE"] = ddiFile; - ppImplicitOuts.push_back(ddiFile); + ppBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile; + ppBuild.ImplicitOuts.push_back(ddiFile); this->DDIFiles[language].push_back(ddiFile); } this->addPoolNinjaVariable("JOB_POOL_COMPILE", this->GetGeneratorTarget(), - ppVars); - - std::string const ppRspFile = ppFileName + ".rsp"; + ppBuild.Variables); - this->GetGlobalGenerator()->WriteBuild( - this->GetBuildFileStream(), ppComment, ppRule, ppOutputs, ppImplicitOuts, - ppExplicitDeps, ppImplicitDeps, ppOrderOnlyDeps, ppVars, ppRspFile, - commandLineLengthLimit); + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), ppBuild, + commandLineLengthLimit); } if (needDyndep) { std::string const dyndep = this->GetDyndepFilePath(language); -- cgit v0.12 From c79b666c432fe5e0f3532d3ea508218f58bbc9a6 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 16:04:52 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmNinjaTargetGenerator.cxx | 53 +++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 47fec28..4c93cf1 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -949,7 +949,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( int const commandLineLengthLimit = ((lang_supports_response && this->ForceResponseFile())) ? -1 : 0; - cmNinjaVars vars; + cmNinjaBuild objBuild(this->LanguageCompilerRule(language)); + cmNinjaVars& vars = objBuild.Variables; vars["FLAGS"] = this->ComputeFlagsForObject(source, language); vars["DEFINES"] = this->ComputeDefines(source, language); vars["INCLUDES"] = this->ComputeIncludes(source, language); @@ -980,32 +981,26 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( language, sourceFileName, objectDir, objectFileName, objectFileDir, vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"]); - std::string comment; - std::string rule = this->LanguageCompilerRule(language); - - cmNinjaDeps outputs; - outputs.push_back(objectFileName); + objBuild.Outputs.push_back(objectFileName); // Add this object to the list of object files. this->Objects.push_back(objectFileName); - cmNinjaDeps explicitDeps; - explicitDeps.push_back(sourceFileName); + objBuild.ExplicitDeps.push_back(sourceFileName); - cmNinjaDeps implicitDeps; if (const char* objectDeps = source->GetProperty("OBJECT_DEPENDS")) { - std::vector depList; - cmSystemTools::ExpandListArgument(objectDeps, depList); + std::vector depList = + cmSystemTools::ExpandedListArgument(objectDeps); for (std::string& odi : depList) { if (cmSystemTools::FileIsFullPath(odi)) { odi = cmSystemTools::CollapseFullPath(odi); } } std::transform(depList.begin(), depList.end(), - std::back_inserter(implicitDeps), MapToNinjaPath()); + std::back_inserter(objBuild.ImplicitDeps), + MapToNinjaPath()); } - cmNinjaDeps orderOnlyDeps; - orderOnlyDeps.push_back(this->OrderDependsTargetForTarget()); + objBuild.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 @@ -1015,8 +1010,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( !source->GetPropertyAsBool("__CMAKE_GENERATED_BY_CMAKE") && !source->GetCustomCommand() && !this->GetGlobalGenerator()->HasCustomCommandOutput(sourceFileName)) { - this->GetGlobalGenerator()->AddAssumedSourceDependencies(sourceFileName, - orderOnlyDeps); + this->GetGlobalGenerator()->AddAssumedSourceDependencies( + sourceFileName, objBuild.OrderOnlyDeps); } // For some cases we need to generate a ninja dyndep file. @@ -1036,18 +1031,18 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( bool const compilePP = this->UsePreprocessedSource(language); if (compilePP) { // Move compilation dependencies to the preprocessing build statement. - std::swap(ppBuild.ExplicitDeps, explicitDeps); - std::swap(ppBuild.ImplicitDeps, implicitDeps); - std::swap(ppBuild.OrderOnlyDeps, orderOnlyDeps); + std::swap(ppBuild.ExplicitDeps, objBuild.ExplicitDeps); + std::swap(ppBuild.ImplicitDeps, objBuild.ImplicitDeps); + std::swap(ppBuild.OrderOnlyDeps, objBuild.OrderOnlyDeps); std::swap(ppBuild.Variables["IN_ABS"], vars["IN_ABS"]); // The actual compilation will now use the preprocessed source. - explicitDeps.push_back(ppFileName); + objBuild.ExplicitDeps.push_back(ppFileName); } else { // Copy compilation dependencies to the preprocessing build statement. - ppBuild.ExplicitDeps = explicitDeps; - ppBuild.ImplicitDeps = implicitDeps; - ppBuild.OrderOnlyDeps = orderOnlyDeps; + ppBuild.ExplicitDeps = objBuild.ExplicitDeps; + ppBuild.ImplicitDeps = objBuild.ImplicitDeps; + ppBuild.OrderOnlyDeps = objBuild.OrderOnlyDeps; ppBuild.Variables["IN_ABS"] = vars["IN_ABS"]; } @@ -1119,7 +1114,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( } if (needDyndep) { std::string const dyndep = this->GetDyndepFilePath(language); - orderOnlyDeps.push_back(dyndep); + objBuild.OrderOnlyDeps.push_back(dyndep); vars["dyndep"] = dyndep; } @@ -1135,15 +1130,13 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( this->SetMsvcTargetPdbVariable(vars); - std::string const rspfile = objectFileName + ".rsp"; + objBuild.RspFile = objectFileName + ".rsp"; if (language == "Swift") { this->EmitSwiftDependencyInfo(source); } else { - this->GetGlobalGenerator()->WriteBuild( - this->GetBuildFileStream(), comment, rule, outputs, - /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, - orderOnlyDeps, vars, rspfile, commandLineLengthLimit); + this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), + objBuild, commandLineLengthLimit); } if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { @@ -1152,7 +1145,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( build.Outputs = cmSystemTools::ExpandedListArgument(objectOutputs); std::transform(build.Outputs.begin(), build.Outputs.end(), build.Outputs.begin(), MapToNinjaPath()); - build.ExplicitDeps = std::move(outputs); + build.ExplicitDeps = objBuild.Outputs; this->GetGlobalGenerator()->WriteBuild(this->GetBuildFileStream(), build); } } -- cgit v0.12 From cba85845172e8e12652e871d6109dba3127e8363 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 16:16:20 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmNinjaNormalTargetGenerator.cxx | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 2e410c8..f214229 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -595,7 +595,6 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() comment << "Link the " << this->GetVisibleTypeName() << " " << targetOutputReal; - cmNinjaDeps emptyDeps; cmNinjaVars vars; // Compute outputs. @@ -758,7 +757,6 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() << "# Link build statements for " << cmState::GetTargetTypeName(targetType) << " target " << this->GetTargetName() << "\n\n"; - cmNinjaDeps emptyDeps; cmNinjaVars vars; // Compute the comment. @@ -1087,14 +1085,16 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() if (symlinkNeeded) { if (targetType == cmStateEnums::EXECUTABLE) { - globalGen.WriteBuild( - this->GetBuildFileStream(), - "Create executable symlink " + targetOutput, - "CMAKE_SYMLINK_EXECUTABLE", cmNinjaDeps(1, targetOutput), - /*implicitOuts=*/cmNinjaDeps(), cmNinjaDeps(1, targetOutputReal), - emptyDeps, emptyDeps, symlinkVars); + cmNinjaBuild build("CMAKE_SYMLINK_EXECUTABLE"); + build.Comment = "Create executable symlink " + targetOutput; + build.Outputs.push_back(targetOutput); + build.ExplicitDeps.push_back(targetOutputReal); + build.Variables = std::move(symlinkVars); + globalGen.WriteBuild(this->GetBuildFileStream(), build); } else { - cmNinjaDeps symlinks; + cmNinjaBuild build("CMAKE_SYMLINK_LIBRARY"); + build.Comment = "Create library symlink " + targetOutput; + std::string const soName = this->ConvertToNinjaPath( this->GetTargetFilePath(this->TargetNames.SharedObject)); // If one link has to be created. @@ -1104,14 +1104,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() soName, cmOutputConverter::SHELL); } else { symlinkVars["SONAME"].clear(); - symlinks.push_back(soName); + build.Outputs.push_back(soName); } - symlinks.push_back(targetOutput); - globalGen.WriteBuild( - this->GetBuildFileStream(), "Create library symlink " + targetOutput, - "CMAKE_SYMLINK_LIBRARY", symlinks, - /*implicitOuts=*/cmNinjaDeps(), cmNinjaDeps(1, targetOutputReal), - emptyDeps, emptyDeps, symlinkVars); + build.Outputs.push_back(targetOutput); + build.ExplicitDeps.push_back(targetOutputReal); + build.Variables = std::move(symlinkVars); + + globalGen.WriteBuild(this->GetBuildFileStream(), build); } } -- cgit v0.12 From 4c9e99e1f9c09e947890e2fe3372ba463904f381 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 16:33:30 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmNinjaNormalTargetGenerator.cxx | 137 +++++++++++++++----------------- 1 file changed, 64 insertions(+), 73 deletions(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index f214229..9c488fb 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -716,18 +716,21 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() void cmNinjaNormalTargetGenerator::WriteLinkStatement() { - cmGeneratorTarget& gt = *this->GetGeneratorTarget(); + cmMakefile* mf = this->GetMakefile(); + cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator(); + cmGeneratorTarget* gt = this->GetGeneratorTarget(); + const std::string cfgName = this->GetConfigName(); - std::string targetOutput = ConvertToNinjaPath(gt.GetFullPath(cfgName)); + std::string targetOutput = ConvertToNinjaPath(gt->GetFullPath(cfgName)); std::string targetOutputReal = ConvertToNinjaPath( - gt.GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact, - /*realname=*/true)); + gt->GetFullPath(cfgName, cmStateEnums::RuntimeBinaryArtifact, + /*realname=*/true)); std::string targetOutputImplib = ConvertToNinjaPath( - gt.GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact)); + gt->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact)); - if (gt.IsAppBundleOnApple()) { + if (gt->IsAppBundleOnApple()) { // Create the app bundle - std::string outpath = gt.GetDirectory(cfgName); + std::string outpath = gt->GetDirectory(cfgName); this->OSXBundleGenerator->CreateAppBundle(this->TargetNames.Output, outpath); @@ -740,33 +743,34 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() targetOutputReal += "/"; targetOutputReal += this->TargetNames.Real; targetOutputReal = this->ConvertToNinjaPath(targetOutputReal); - } else if (gt.IsFrameworkOnApple()) { + } else if (gt->IsFrameworkOnApple()) { // Create the library framework. this->OSXBundleGenerator->CreateFramework(this->TargetNames.Output, - gt.GetDirectory(cfgName)); - } else if (gt.IsCFBundleOnApple()) { + gt->GetDirectory(cfgName)); + } else if (gt->IsCFBundleOnApple()) { // Create the core foundation bundle. this->OSXBundleGenerator->CreateCFBundle(this->TargetNames.Output, - gt.GetDirectory(cfgName)); + gt->GetDirectory(cfgName)); } // Write comments. cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); - const cmStateEnums::TargetType targetType = gt.GetType(); + const cmStateEnums::TargetType targetType = gt->GetType(); this->GetBuildFileStream() << "# Link build statements for " << cmState::GetTargetTypeName(targetType) << " target " << this->GetTargetName() << "\n\n"; - cmNinjaVars vars; + cmNinjaBuild linkBuild(this->LanguageLinkerRule()); + cmNinjaVars& vars = linkBuild.Variables; // Compute the comment. - std::ostringstream comment; - comment << "Link the " << this->GetVisibleTypeName() << " " - << targetOutputReal; + linkBuild.Comment = "Link the "; + linkBuild.Comment += this->GetVisibleTypeName(); + linkBuild.Comment += " "; + linkBuild.Comment += targetOutputReal; // Compute outputs. - cmNinjaDeps outputs; - outputs.push_back(targetOutputReal); + linkBuild.Outputs.push_back(targetOutputReal); if (this->TargetLinkLanguage == "Swift") { vars["SWIFT_LIBRARY_NAME"] = [this]() -> std::string { @@ -775,12 +779,11 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() return targetNames.Base; }(); - vars["SWIFT_MODULE_NAME"] = [this]() -> std::string { - if (const char* name = - this->GetGeneratorTarget()->GetProperty("Swift_MODULE_NAME")) { + vars["SWIFT_MODULE_NAME"] = [gt]() -> std::string { + if (const char* name = gt->GetProperty("Swift_MODULE_NAME")) { return name; } - return this->GetGeneratorTarget()->GetName(); + return gt->GetName(); }(); vars["SWIFT_MODULE"] = [this](const std::string& module) -> std::string { @@ -804,7 +807,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() vars["SWIFT_OUTPUT_FILE_MAP"] = this->GetLocalGenerator()->ConvertToOutputFormat( - this->ConvertToNinjaPath(gt.GetSupportDirectory() + + this->ConvertToNinjaPath(gt->GetSupportDirectory() + "/output-file-map.json"), cmOutputConverter::SHELL); @@ -833,35 +836,31 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } // Compute specific libraries to link with. - cmNinjaDeps explicitDeps; if (this->TargetLinkLanguage == "Swift") { std::vector sources; - this->GetGeneratorTarget()->GetObjectSources(sources, - this->GetConfigName()); + gt->GetObjectSources(sources, this->GetConfigName()); for (const auto& source : sources) { - outputs.push_back( + linkBuild.Outputs.push_back( this->ConvertToNinjaPath(this->GetObjectFilePath(source))); - explicitDeps.push_back( + linkBuild.ExplicitDeps.push_back( this->ConvertToNinjaPath(this->GetSourceFilePath(source))); } - outputs.push_back(vars["SWIFT_MODULE"]); + linkBuild.Outputs.push_back(vars["SWIFT_MODULE"]); } else { - explicitDeps = this->GetObjects(); + linkBuild.ExplicitDeps = this->GetObjects(); } - cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); + linkBuild.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); if (!this->DeviceLinkObject.empty()) { - explicitDeps.push_back(this->DeviceLinkObject); + linkBuild.ExplicitDeps.push_back(this->DeviceLinkObject); } - cmMakefile* mf = this->GetMakefile(); - std::string frameworkPath; std::string linkPath; std::string createRule = - gt.GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName()); + gt->GetCreateRuleVariable(this->TargetLinkLanguage, this->GetConfigName()); bool useWatcomQuote = mf->IsOn(createRule + "_USE_WATCOM_QUOTE"); cmLocalNinjaGenerator& localGen = *this->GetLocalGenerator(); @@ -869,14 +868,14 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() localGen.ConvertToOutputFormat(targetOutputReal, cmOutputConverter::SHELL); std::unique_ptr linkLineComputer( - this->GetGlobalGenerator()->CreateLinkLineComputer( + globalGen->CreateLinkLineComputer( this->GetLocalGenerator(), this->GetLocalGenerator()->GetStateSnapshot().GetDirectory())); linkLineComputer->SetUseWatcomQuote(useWatcomQuote); localGen.GetTargetFlags(linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"], vars["FLAGS"], - vars["LINK_FLAGS"], frameworkPath, linkPath, >); + vars["LINK_FLAGS"], frameworkPath, linkPath, gt); // Add OS X version flags, if any. if (this->GeneratorTarget->GetType() == cmStateEnums::SHARED_LIBRARY || @@ -887,7 +886,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() "CURRENT", false); } - this->addPoolNinjaVariable("JOB_POOL_LINK", >, vars); + this->addPoolNinjaVariable("JOB_POOL_LINK", gt, vars); this->AddModuleDefinitionFlag(linkLineComputer.get(), vars["LINK_FLAGS"]); vars["LINK_FLAGS"] = @@ -897,7 +896,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() vars["LINK_PATH"] = frameworkPath + linkPath; std::string lwyuFlags; - if (gt.GetPropertyAsBool("LINK_WHAT_YOU_USE")) { + if (gt->GetPropertyAsBool("LINK_WHAT_YOU_USE")) { lwyuFlags = " -Wl,--no-as-needed"; } @@ -906,24 +905,23 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // code between the Makefile executable and library generators. if (targetType == cmStateEnums::EXECUTABLE) { std::string t = vars["FLAGS"]; - localGen.AddArchitectureFlags(t, >, TargetLinkLanguage, cfgName); + localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName); t += lwyuFlags; vars["FLAGS"] = t; } else { std::string t = vars["ARCH_FLAGS"]; - localGen.AddArchitectureFlags(t, >, TargetLinkLanguage, cfgName); + localGen.AddArchitectureFlags(t, gt, TargetLinkLanguage, cfgName); vars["ARCH_FLAGS"] = t; t.clear(); t += lwyuFlags; - localGen.AddLanguageFlagsForLinking(t, >, TargetLinkLanguage, cfgName); + localGen.AddLanguageFlagsForLinking(t, gt, TargetLinkLanguage, cfgName); vars["LANGUAGE_COMPILE_FLAGS"] = t; } - if (this->GetGeneratorTarget()->HasSOName(cfgName)) { + if (gt->HasSOName(cfgName)) { vars["SONAME_FLAG"] = mf->GetSONameFlag(this->TargetLinkLanguage); vars["SONAME"] = this->TargetNames.SharedObject; if (targetType == cmStateEnums::SHARED_LIBRARY) { - std::string install_dir = - this->GetGeneratorTarget()->GetInstallNameDirForBuildTree(cfgName); + std::string install_dir = gt->GetInstallNameDirForBuildTree(cfgName); if (!install_dir.empty()) { vars["INSTALLNAME_DIR"] = localGen.ConvertToOutputFormat( install_dir, cmOutputConverter::SHELL); @@ -938,7 +936,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() targetOutputImplib, cmOutputConverter::SHELL); vars["TARGET_IMPLIB"] = impLibPath; EnsureParentDirectoryExists(impLibPath); - if (gt.HasImportLibrary(cfgName)) { + if (gt->HasImportLibrary(cfgName)) { byproducts.push_back(targetOutputImplib); } } @@ -949,7 +947,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() std::string prefix; std::string base; std::string suffix; - this->GetGeneratorTarget()->GetFullNameComponents(prefix, base, suffix); + gt->GetFullNameComponents(prefix, base, suffix); std::string dbg_suffix = ".dbg"; // TODO: Where to document? if (mf->GetDefinition("CMAKE_DEBUG_SYMBOL_SUFFIX")) { @@ -958,12 +956,12 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() vars["TARGET_PDB"] = base + suffix + dbg_suffix; } - const std::string objPath = GetGeneratorTarget()->GetSupportDirectory(); + const std::string objPath = gt->GetSupportDirectory(); vars["OBJECT_DIR"] = this->GetLocalGenerator()->ConvertToOutputFormat( this->ConvertToNinjaPath(objPath), cmOutputConverter::SHELL); EnsureDirectoryExists(objPath); - if (this->GetGlobalGenerator()->IsGCCOnWindows()) { + if (globalGen->IsGCCOnWindows()) { // ar.exe can't handle backslashes in rsp files (implicitly used by gcc) std::string& linkLibraries = vars["LINK_LIBRARIES"]; std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/'); @@ -972,8 +970,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } const std::vector* cmdLists[3] = { - >.GetPreBuildCommands(), >.GetPreLinkCommands(), - >.GetPostBuildCommands() + >->GetPreBuildCommands(), >->GetPreLinkCommands(), + >->GetPostBuildCommands() }; std::vector preLinkCmdLines, postBuildCmdLines; @@ -993,7 +991,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // maybe create .def file from list of objects cmGeneratorTarget::ModuleDefinitionInfo const* mdi = - gt.GetModuleDefinitionInfo(this->GetConfigName()); + gt->GetModuleDefinitionInfo(this->GetConfigName()); if (mdi && mdi->DefFileGenerated) { std::string cmakeCommand = this->GetLocalGenerator()->ConvertToOutputFormat( @@ -1025,8 +1023,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() } } // If we have any PRE_LINK commands, we need to go back to CMAKE_BINARY_DIR - // for - // the link commands. + // for the link commands. if (!preLinkCmdLines.empty()) { const std::string homeOutDir = localGen.ConvertToOutputFormat( localGen.GetBinaryDirectory(), cmOutputConverter::SHELL); @@ -1040,14 +1037,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() cmNinjaVars symlinkVars; bool const symlinkNeeded = - (targetOutput != targetOutputReal && !gt.IsFrameworkOnApple()); + (targetOutput != targetOutputReal && !gt->IsFrameworkOnApple()); if (!symlinkNeeded) { vars["POST_BUILD"] = postBuildCmdLine; } else { vars["POST_BUILD"] = cmGlobalNinjaGenerator::SHELL_NOOP; symlinkVars["POST_BUILD"] = postBuildCmdLine; } - cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator(); bool const lang_supports_response = !(this->TargetLinkLanguage == "RC" || this->TargetLinkLanguage == "CUDA"); @@ -1055,32 +1051,27 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() if (!lang_supports_response || !this->ForceResponseFile()) { commandLineLengthLimit = static_cast(cmSystemTools::CalculateCommandLineLengthLimit()) - - globalGen.GetRuleCmdLength(this->LanguageLinkerRule()); + globalGen->GetRuleCmdLength(linkBuild.Rule); } - const std::string rspfile = this->ConvertToNinjaPath( - std::string("CMakeFiles/") + gt.GetName() + ".rsp"); + linkBuild.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") + + gt->GetName() + ".rsp"); // Gather order-only dependencies. - cmNinjaDeps orderOnlyDeps; - this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(), - orderOnlyDeps); + this->GetLocalGenerator()->AppendTargetDepends(gt, linkBuild.OrderOnlyDeps); // Ninja should restat after linking if and only if there are byproducts. vars["RESTAT"] = byproducts.empty() ? "" : "1"; for (std::string const& o : byproducts) { - this->GetGlobalGenerator()->SeenCustomCommandOutput(o); - outputs.push_back(o); + globalGen->SeenCustomCommandOutput(o); + linkBuild.Outputs.push_back(o); } // Write the build statement for this target. bool usedResponseFile = false; - globalGen.WriteBuild(this->GetBuildFileStream(), comment.str(), - this->LanguageLinkerRule(), outputs, - /*implicitOuts=*/cmNinjaDeps(), explicitDeps, - implicitDeps, orderOnlyDeps, vars, rspfile, - commandLineLengthLimit, &usedResponseFile); + globalGen->WriteBuild(this->GetBuildFileStream(), linkBuild, + commandLineLengthLimit, &usedResponseFile); this->WriteLinkRule(usedResponseFile); if (symlinkNeeded) { @@ -1090,7 +1081,7 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() build.Outputs.push_back(targetOutput); build.ExplicitDeps.push_back(targetOutputReal); build.Variables = std::move(symlinkVars); - globalGen.WriteBuild(this->GetBuildFileStream(), build); + globalGen->WriteBuild(this->GetBuildFileStream(), build); } else { cmNinjaBuild build("CMAKE_SYMLINK_LIBRARY"); build.Comment = "Create library symlink " + targetOutput; @@ -1110,13 +1101,13 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() build.ExplicitDeps.push_back(targetOutputReal); build.Variables = std::move(symlinkVars); - globalGen.WriteBuild(this->GetBuildFileStream(), build); + globalGen->WriteBuild(this->GetBuildFileStream(), build); } } // Add aliases for the file name and the target name. - globalGen.AddTargetAlias(this->TargetNames.Output, >); - globalGen.AddTargetAlias(this->GetTargetName(), >); + globalGen->AddTargetAlias(this->TargetNames.Output, gt); + globalGen->AddTargetAlias(this->GetTargetName(), gt); } void cmNinjaNormalTargetGenerator::WriteObjectLibStatement() -- cgit v0.12 From 465d6d7f9b53aeaab4b388f30adc324fae8ab4c8 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 16:41:50 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmNinjaNormalTargetGenerator.cxx | 64 ++++++++++++++++----------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index 9c488fb..1399ee2 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -554,11 +554,12 @@ std::vector cmNinjaNormalTargetGenerator::ComputeLinkCmd() void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() { - if (!this->GetGlobalGenerator()->GetLanguageEnabled("CUDA")) { + cmGlobalNinjaGenerator* globalGen = this->GetGlobalGenerator(); + if (!globalGen->GetLanguageEnabled("CUDA")) { return; } - cmGeneratorTarget& genTarget = *this->GetGeneratorTarget(); + cmGeneratorTarget* genTarget = this->GetGeneratorTarget(); bool requiresDeviceLinking = requireDeviceLinking( *this->GeneratorTarget, *this->GetLocalGenerator(), this->ConfigName); @@ -576,38 +577,39 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() std::string const cfgName = this->GetConfigName(); std::string const targetOutputReal = ConvertToNinjaPath( - genTarget.ObjectDirectory + "cmake_device_link" + objExt); + genTarget->ObjectDirectory + "cmake_device_link" + objExt); std::string const targetOutputImplib = ConvertToNinjaPath( - genTarget.GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact)); + genTarget->GetFullPath(cfgName, cmStateEnums::ImportLibraryArtifact)); this->DeviceLinkObject = targetOutputReal; // Write comments. cmGlobalNinjaGenerator::WriteDivider(this->GetBuildFileStream()); - const cmStateEnums::TargetType targetType = genTarget.GetType(); + const cmStateEnums::TargetType targetType = genTarget->GetType(); this->GetBuildFileStream() << "# Device Link build statements for " << cmState::GetTargetTypeName(targetType) << " target " << this->GetTargetName() << "\n\n"; // Compute the comment. - std::ostringstream comment; - comment << "Link the " << this->GetVisibleTypeName() << " " - << targetOutputReal; + cmNinjaBuild build(this->LanguageLinkerDeviceRule()); + build.Comment = "Link the "; + build.Comment += this->GetVisibleTypeName(); + build.Comment += " "; + build.Comment += targetOutputReal; - cmNinjaVars vars; + cmNinjaVars& vars = build.Variables; // Compute outputs. - cmNinjaDeps outputs; - outputs.push_back(targetOutputReal); + build.Outputs.push_back(targetOutputReal); // Compute specific libraries to link with. - cmNinjaDeps explicitDeps = this->GetObjects(); - cmNinjaDeps implicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); + build.ExplicitDeps = this->GetObjects(); + build.ImplicitDeps = this->ComputeLinkDeps(this->TargetLinkLanguage); std::string frameworkPath; std::string linkPath; - std::string createRule = genTarget.GetCreateRuleVariable( + std::string createRule = genTarget->GetCreateRuleVariable( this->TargetLinkLanguage, this->GetConfigName()); const bool useWatcomQuote = this->GetMakefile()->IsOn(createRule + "_USE_WATCOM_QUOTE"); @@ -620,14 +622,14 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() new cmNinjaLinkLineDeviceComputer( this->GetLocalGenerator(), this->GetLocalGenerator()->GetStateSnapshot().GetDirectory(), - this->GetGlobalGenerator())); + globalGen)); linkLineComputer->SetUseWatcomQuote(useWatcomQuote); localGen.GetTargetFlags( linkLineComputer.get(), this->GetConfigName(), vars["LINK_LIBRARIES"], - vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, &genTarget); + vars["FLAGS"], vars["LINK_FLAGS"], frameworkPath, linkPath, genTarget); - this->addPoolNinjaVariable("JOB_POOL_LINK", &genTarget, vars); + this->addPoolNinjaVariable("JOB_POOL_LINK", genTarget, vars); vars["LINK_FLAGS"] = cmGlobalNinjaGenerator::EncodeLiteral(vars["LINK_FLAGS"]); @@ -641,18 +643,18 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() // code between the Makefile executable and library generators. if (targetType == cmStateEnums::EXECUTABLE) { std::string t = vars["FLAGS"]; - localGen.AddArchitectureFlags(t, &genTarget, cudaLinkLanguage, cfgName); + localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName); vars["FLAGS"] = t; } else { std::string t = vars["ARCH_FLAGS"]; - localGen.AddArchitectureFlags(t, &genTarget, cudaLinkLanguage, cfgName); + localGen.AddArchitectureFlags(t, genTarget, cudaLinkLanguage, cfgName); vars["ARCH_FLAGS"] = t; t.clear(); - localGen.AddLanguageFlagsForLinking(t, &genTarget, cudaLinkLanguage, + localGen.AddLanguageFlagsForLinking(t, genTarget, cudaLinkLanguage, cfgName); vars["LANGUAGE_COMPILE_FLAGS"] = t; } - if (this->GetGeneratorTarget()->HasSOName(cfgName)) { + if (genTarget->HasSOName(cfgName)) { vars["SONAME_FLAG"] = this->GetMakefile()->GetSONameFlag(this->TargetLinkLanguage); vars["SONAME"] = this->TargetNames.SharedObject; @@ -680,7 +682,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() this->SetMsvcTargetPdbVariable(vars); - if (this->GetGlobalGenerator()->IsGCCOnWindows()) { + if (globalGen->IsGCCOnWindows()) { // ar.exe can't handle backslashes in rsp files (implicitly used by gcc) std::string& linkLibraries = vars["LINK_LIBRARIES"]; std::replace(linkLibraries.begin(), linkLibraries.end(), '\\', '/'); @@ -688,29 +690,23 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkStatement() std::replace(link_path.begin(), link_path.end(), '\\', '/'); } - cmGlobalNinjaGenerator& globalGen = *this->GetGlobalGenerator(); - // Device linking currently doesn't support response files so // do not check if the user has explicitly forced a response file. int const commandLineLengthLimit = static_cast(cmSystemTools::CalculateCommandLineLengthLimit()) - - globalGen.GetRuleCmdLength(this->LanguageLinkerDeviceRule()); + globalGen->GetRuleCmdLength(this->LanguageLinkerDeviceRule()); - const std::string rspfile = this->ConvertToNinjaPath( - std::string("CMakeFiles/") + genTarget.GetName() + ".rsp"); + build.RspFile = this->ConvertToNinjaPath(std::string("CMakeFiles/") + + genTarget->GetName() + ".rsp"); // Gather order-only dependencies. - cmNinjaDeps orderOnlyDeps; this->GetLocalGenerator()->AppendTargetDepends(this->GetGeneratorTarget(), - orderOnlyDeps); + build.OrderOnlyDeps); // Write the build statement for this target. bool usedResponseFile = false; - globalGen.WriteBuild(this->GetBuildFileStream(), comment.str(), - this->LanguageLinkerDeviceRule(), outputs, - /*implicitOuts=*/cmNinjaDeps(), explicitDeps, - implicitDeps, orderOnlyDeps, vars, rspfile, - commandLineLengthLimit, &usedResponseFile); + globalGen->WriteBuild(this->GetBuildFileStream(), build, + commandLineLengthLimit, &usedResponseFile); this->WriteDeviceLinkRule(false); } -- cgit v0.12 From 834ec4ebfe982ff75b2a34bac2515d221bc3ab38 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 17:12:15 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmGlobalNinjaGenerator.cxx | 57 +++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index cde764f..265fe7d 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1342,20 +1342,21 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) WriteRule(*this->RulesFileStream, rule); } - cmNinjaDeps implicitDeps; - cmNinjaDeps explicitDeps; + cmNinjaBuild reBuild("RERUN_CMAKE"); + reBuild.Comment = "Re-run CMake if any of its inputs changed."; + reBuild.Outputs.push_back(this->NinjaOutputPath(NINJA_BUILD_FILE)); + for (cmLocalGenerator* localGen : this->LocalGenerators) { for (std::string const& fi : localGen->GetMakefile()->GetListFiles()) { - implicitDeps.push_back(this->ConvertToNinjaPath(fi)); + reBuild.ImplicitDeps.push_back(this->ConvertToNinjaPath(fi)); } } - implicitDeps.push_back(this->CMakeCacheFile); + reBuild.ImplicitDeps.push_back(this->CMakeCacheFile); - cmNinjaVars variables; // Use 'console' pool to get non buffered output of the CMake re-run call // Available since Ninja 1.5 if (SupportsConsolePool()) { - variables["pool"] = "console"; + reBuild.Variables["pool"] = "console"; } cmake* cm = this->GetCMakeInstance(); @@ -1377,23 +1378,23 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) phonyBuild.Outputs.push_back(cm->GetGlobVerifyScript() + "_force"); this->WriteBuild(os, phonyBuild); - variables["restat"] = "1"; + reBuild.Variables["restat"] = "1"; std::string const verifyScriptFile = this->NinjaOutputPath(cm->GetGlobVerifyScript()); std::string const verifyStampFile = this->NinjaOutputPath(cm->GetGlobVerifyStamp()); - this->WriteBuild(os, - "Re-run CMake to check if globbed directories changed.", - "VERIFY_GLOBS", - /*outputs=*/cmNinjaDeps(1, verifyStampFile), - /*implicitOuts=*/cmNinjaDeps(), - /*explicitDeps=*/cmNinjaDeps(), - /*implicitDeps=*/phonyBuild.Outputs, - /*orderOnlyDeps=*/cmNinjaDeps(), variables); - - variables.erase("restat"); - implicitDeps.push_back(verifyScriptFile); - explicitDeps.push_back(verifyStampFile); + { + cmNinjaBuild vgBuild("VERIFY_GLOBS"); + vgBuild.Comment = + "Re-run CMake to check if globbed directories changed."; + vgBuild.Outputs.push_back(verifyStampFile); + vgBuild.ImplicitDeps = phonyBuild.Outputs; + vgBuild.Variables = reBuild.Variables; + this->WriteBuild(os, vgBuild); + } + reBuild.Variables.erase("restat"); + reBuild.ImplicitDeps.push_back(verifyScriptFile); + reBuild.ExplicitDeps.push_back(verifyStampFile); } else if (!this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) { std::ostringstream msg; @@ -1411,22 +1412,18 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) msg.str()); } - std::sort(implicitDeps.begin(), implicitDeps.end()); - implicitDeps.erase(std::unique(implicitDeps.begin(), implicitDeps.end()), - implicitDeps.end()); + std::sort(reBuild.ImplicitDeps.begin(), reBuild.ImplicitDeps.end()); + reBuild.ImplicitDeps.erase( + std::unique(reBuild.ImplicitDeps.begin(), reBuild.ImplicitDeps.end()), + reBuild.ImplicitDeps.end()); - std::string const ninjaBuildFile = this->NinjaOutputPath(NINJA_BUILD_FILE); - this->WriteBuild(os, "Re-run CMake if any of its inputs changed.", - "RERUN_CMAKE", - /*outputs=*/cmNinjaDeps(1, ninjaBuildFile), - /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, - /*orderOnlyDeps=*/cmNinjaDeps(), variables); + this->WriteBuild(os, reBuild); { cmNinjaBuild build("phony"); build.Comment = "A missing CMake input file is not an error."; - std::set_difference(std::make_move_iterator(implicitDeps.begin()), - std::make_move_iterator(implicitDeps.end()), + std::set_difference(std::make_move_iterator(reBuild.ImplicitDeps.begin()), + std::make_move_iterator(reBuild.ImplicitDeps.end()), CustomCommandOutputs.begin(), CustomCommandOutputs.end(), std::back_inserter(build.Outputs)); -- cgit v0.12 From 7fd3811400b9b2483d635dbcc1b0bfab268527df Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 17:18:36 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmGlobalNinjaGenerator.cxx | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 265fe7d..fb4f41d 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1515,16 +1515,11 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) // Write build { - cmNinjaDeps outputs; - outputs.emplace_back( + cmNinjaBuild build("CLEAN_ADDITIONAL"); + build.Comment = "Clean additional files."; + build.Outputs.push_back( this->NinjaOutputPath(this->GetAdditionalCleanTargetName())); - WriteBuild(os, "Clean additional files.", "CLEAN_ADDITIONAL", - /*outputs=*/outputs, - /*implicitOuts=*/cmNinjaDeps(), - /*explicitDeps=*/cmNinjaDeps(), - /*implicitDeps=*/cmNinjaDeps(), - /*orderOnlyDeps=*/cmNinjaDeps(), - /*variables=*/cmNinjaVars()); + WriteBuild(os, build); } // Return success return true; -- cgit v0.12 From 409922f695df4fc885d04338f56dcfb4dc406f7d Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 17:20:28 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmGlobalNinjaGenerator.cxx | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index fb4f41d..c6e4be4 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1542,20 +1542,14 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) // Write build { - cmNinjaDeps explicitDeps; + cmNinjaBuild build("CLEAN"); + build.Comment = "Clean all the built files."; + build.Outputs.push_back(this->NinjaOutputPath(this->GetCleanTargetName())); if (additionalFiles) { - explicitDeps.emplace_back( + build.ExplicitDeps.push_back( this->NinjaOutputPath(this->GetAdditionalCleanTargetName())); } - cmNinjaDeps outputs; - outputs.emplace_back(this->NinjaOutputPath(this->GetCleanTargetName())); - WriteBuild(os, "Clean all the built files.", "CLEAN", - /*outputs=*/outputs, - /*implicitOuts=*/cmNinjaDeps(), - /*explicitDeps=*/explicitDeps, - /*implicitDeps=*/cmNinjaDeps(), - /*orderOnlyDeps=*/cmNinjaDeps(), - /*variables=*/cmNinjaVars()); + WriteBuild(os, build); } } -- cgit v0.12 From df06c8d7921d09a2a627731866a8ce895990067b Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 17:22:56 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmGlobalNinjaGenerator.cxx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index c6e4be4..ed604d9 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1562,13 +1562,12 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) rule.Comment = "Rule for printing all primary targets available."; WriteRule(*this->RulesFileStream, rule); } - WriteBuild(os, "Print all primary targets available.", "HELP", - /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("help")), - /*implicitOuts=*/cmNinjaDeps(), - /*explicitDeps=*/cmNinjaDeps(), - /*implicitDeps=*/cmNinjaDeps(), - /*orderOnlyDeps=*/cmNinjaDeps(), - /*variables=*/cmNinjaVars()); + { + cmNinjaBuild build("HELP"); + build.Comment = "Print all primary targets available."; + build.Outputs.push_back(this->NinjaOutputPath("help")); + WriteBuild(os, build); + } } void cmGlobalNinjaGenerator::InitOutputPathPrefix() -- cgit v0.12 From ccf950795666406e59f420fd2732149711cb0362 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 17:29:06 +0200 Subject: Ninja: Use cmNinjaBuild class for WriteBuild --- Source/cmGlobalNinjaGenerator.cxx | 45 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index ed604d9..db0e01c 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -1940,32 +1940,29 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile( cmGeneratedFileStream ddf(arg_dd); ddf << "ninja_dyndep_version = 1.0\n"; - for (cmDyndepObjectInfo const& object : objects) { - std::string const ddComment; - std::string const ddRule = "dyndep"; - cmNinjaDeps ddOutputs; - cmNinjaDeps ddImplicitOuts; - cmNinjaDeps ddExplicitDeps; - cmNinjaDeps ddImplicitDeps; - cmNinjaDeps ddOrderOnlyDeps; - cmNinjaVars ddVars; - - ddOutputs.push_back(object.Object); - for (std::string const& p : object.Provides) { - ddImplicitOuts.push_back(this->ConvertToNinjaPath(mod_files[p])); - } - for (std::string const& r : object.Requires) { - std::map::iterator m = mod_files.find(r); - if (m != mod_files.end()) { - ddImplicitDeps.push_back(this->ConvertToNinjaPath(m->second)); + { + cmNinjaBuild build("dyndep"); + build.Outputs.emplace_back(""); + for (cmDyndepObjectInfo const& object : objects) { + build.Outputs[0] = object.Object; + build.ImplicitOuts.clear(); + for (std::string const& p : object.Provides) { + build.ImplicitOuts.push_back(this->ConvertToNinjaPath(mod_files[p])); + } + build.ImplicitDeps.clear(); + for (std::string const& r : object.Requires) { + auto mit = mod_files.find(r); + if (mit != mod_files.end()) { + build.ImplicitDeps.push_back(this->ConvertToNinjaPath(mit->second)); + } + } + build.Variables.clear(); + if (!object.Provides.empty()) { + build.Variables.emplace("restat", "1"); } - } - if (!object.Provides.empty()) { - ddVars["restat"] = "1"; - } - this->WriteBuild(ddf, ddComment, ddRule, ddOutputs, ddImplicitOuts, - ddExplicitDeps, ddImplicitDeps, ddOrderOnlyDeps, ddVars); + this->WriteBuild(ddf, build); + } } // Store the map of modules provided by this target in a file for -- cgit v0.12 From 7d9e66a405ccd44fe3271278449ce0887a462d41 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 30 May 2019 17:39:22 +0200 Subject: Ninja: Remove non cmNinjaBuild based WriteBuild method --- Source/cmGlobalNinjaGenerator.cxx | 156 ++++++++++++++++++-------------------- Source/cmGlobalNinjaGenerator.h | 16 ---- 2 files changed, 75 insertions(+), 97 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index db0e01c..2d52356 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -127,113 +127,107 @@ std::string cmGlobalNinjaGenerator::EncodePath(const std::string& path) return result; } -void cmGlobalNinjaGenerator::WriteBuild( - std::ostream& os, const std::string& comment, const std::string& rule, - const cmNinjaDeps& outputs, const cmNinjaDeps& implicitOuts, - const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, - const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables, - const std::string& rspfile, int cmdLineLimit, bool* usedResponseFile) +void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, + cmNinjaBuild const& build, + int cmdLineLimit, + bool* usedResponseFile) { // Make sure there is a rule. - if (rule.empty()) { + if (build.Rule.empty()) { cmSystemTools::Error("No rule for WriteBuild! called with comment: " + - comment); + build.Comment); return; } // Make sure there is at least one output file. - if (outputs.empty()) { + if (build.Outputs.empty()) { cmSystemTools::Error( - "No output files for WriteBuild! called with comment: " + comment); + "No output files for WriteBuild! called with comment: " + build.Comment); return; } - cmGlobalNinjaGenerator::WriteComment(os, comment); - - std::string arguments; - - // TODO: Better formatting for when there are multiple input/output files. - - // Write explicit dependencies. - for (std::string const& explicitDep : explicitDeps) { - arguments += " " + EncodePath(explicitDep); - } + cmGlobalNinjaGenerator::WriteComment(os, build.Comment); - // Write implicit dependencies. - if (!implicitDeps.empty()) { - arguments += " |"; - for (std::string const& implicitDep : implicitDeps) { - arguments += " " + EncodePath(implicitDep); + // Write output files. + std::string buildStr("build"); + { + // Write explicit outputs + for (std::string const& output : build.Outputs) { + buildStr += " " + EncodePath(output); + if (this->ComputingUnknownDependencies) { + this->CombinedBuildOutputs.insert(output); + } } - } - - // Write order-only dependencies. - if (!orderOnlyDeps.empty()) { - arguments += " ||"; - for (std::string const& orderOnlyDep : orderOnlyDeps) { - arguments += " " + EncodePath(orderOnlyDep); + // Write implicit outputs + if (!build.ImplicitOuts.empty()) { + buildStr += " |"; + for (std::string const& implicitOut : build.ImplicitOuts) { + buildStr += " " + EncodePath(implicitOut); + } } + buildStr += ":"; + + // Write the rule. + buildStr += " "; + buildStr += build.Rule; } - arguments += "\n"; + std::string arguments; + { + // TODO: Better formatting for when there are multiple input/output files. - std::string build; + // Write explicit dependencies. + for (std::string const& explicitDep : build.ExplicitDeps) { + arguments += " " + EncodePath(explicitDep); + } - // Write outputs files. - build += "build"; - for (std::string const& output : outputs) { - build += " " + EncodePath(output); - if (this->ComputingUnknownDependencies) { - this->CombinedBuildOutputs.insert(output); + // Write implicit dependencies. + if (!build.ImplicitDeps.empty()) { + arguments += " |"; + for (std::string const& implicitDep : build.ImplicitDeps) { + arguments += " " + EncodePath(implicitDep); + } } - } - if (!implicitOuts.empty()) { - build += " |"; - for (std::string const& implicitOut : implicitOuts) { - build += " " + EncodePath(implicitOut); + + // Write order-only dependencies. + if (!build.OrderOnlyDeps.empty()) { + arguments += " ||"; + for (std::string const& orderOnlyDep : build.OrderOnlyDeps) { + arguments += " " + EncodePath(orderOnlyDep); + } } - } - build += ":"; - // Write the rule. - build += " " + rule; + arguments += "\n"; + } // Write the variables bound to this build statement. - std::ostringstream variable_assignments; - for (auto const& variable : variables) { - cmGlobalNinjaGenerator::WriteVariable(variable_assignments, variable.first, - variable.second, "", 1); - } + std::string assignments; + { + std::ostringstream variable_assignments; + for (auto const& variable : build.Variables) { + cmGlobalNinjaGenerator::WriteVariable( + variable_assignments, variable.first, variable.second, "", 1); + } - // check if a response file rule should be used - std::string buildstr = build; - std::string assignments = variable_assignments.str(); - bool useResponseFile = false; - if (cmdLineLimit < 0 || - (cmdLineLimit > 0 && - (arguments.size() + buildstr.size() + assignments.size() + 1000) > - static_cast(cmdLineLimit))) { - variable_assignments.str(std::string()); - cmGlobalNinjaGenerator::WriteVariable(variable_assignments, "RSP_FILE", - rspfile, "", 1); - assignments += variable_assignments.str(); - useResponseFile = true; - } - if (usedResponseFile) { - *usedResponseFile = useResponseFile; + // check if a response file rule should be used + assignments = variable_assignments.str(); + bool useResponseFile = false; + if (cmdLineLimit < 0 || + (cmdLineLimit > 0 && + (arguments.size() + buildStr.size() + assignments.size() + 1000) > + static_cast(cmdLineLimit))) { + variable_assignments.str(std::string()); + cmGlobalNinjaGenerator::WriteVariable(variable_assignments, "RSP_FILE", + build.RspFile, "", 1); + assignments += variable_assignments.str(); + useResponseFile = true; + } + if (usedResponseFile) { + *usedResponseFile = useResponseFile; + } } - os << buildstr << arguments << assignments; -} - -void cmGlobalNinjaGenerator::WriteBuild(std::ostream& os, - cmNinjaBuild const& build, - int cmdLineLimit, - bool* usedResponseFile) -{ - WriteBuild(os, build.Comment, build.Rule, build.Outputs, build.ImplicitOuts, - build.ExplicitDeps, build.ImplicitDeps, build.OrderOnlyDeps, - build.Variables, build.RspFile, cmdLineLimit, usedResponseFile); + os << buildStr << arguments << assignments << "\n"; } void cmGlobalNinjaGenerator::AddCustomCommandRule() diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index 4ccd927..15dd404 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -101,22 +101,6 @@ public: bool IsIPOSupported() const override { return true; } /** - * Write a build statement to @a os with the @a comment using - * the @a rule the list of @a outputs files and inputs. - * It also writes the variables bound to this build statement. - * @warning no escaping of any kind is done here. - */ - void WriteBuild(std::ostream& os, const std::string& comment, - const std::string& rule, const cmNinjaDeps& outputs, - const cmNinjaDeps& implicitOuts, - const cmNinjaDeps& explicitDeps, - const cmNinjaDeps& implicitDeps, - const cmNinjaDeps& orderOnlyDeps, - const cmNinjaVars& variables, - const std::string& rspfile = std::string(), - int cmdLineLimit = 0, bool* usedResponseFile = nullptr); - - /** * Write a build statement @a build to @a os. * @warning no escaping of any kind is done here. */ -- cgit v0.12