From 144a24dcdcbb075d60d31171e0bda0654e613287 Mon Sep 17 00:00:00 2001 From: Brad King Date: Mon, 19 Sep 2016 15:49:13 -0400 Subject: [PATCH] cmGlobalNinjaGenerator: Teach WriteBuild about implicit outputs Ninja 1.7 introduced support for implicit outputs on build statements. Teach WriteBuild to generate the corresponding syntax. Leave it up to callers to decide whether implicit outputs are supported by the Ninja version in use. For now simply update all call sites to pass an empty list of implicit outputs. --- Source/cmGlobalNinjaGenerator.cxx | 27 ++++++++++++++++++------- Source/cmGlobalNinjaGenerator.h | 1 + Source/cmNinjaNormalTargetGenerator.cxx | 9 ++++++--- Source/cmNinjaTargetGenerator.cxx | 5 +++-- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index bd65366da..c74baa180 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -140,10 +140,10 @@ std::string cmGlobalNinjaGenerator::EncodeDepfileSpace(const std::string& path) void cmGlobalNinjaGenerator::WriteBuild( std::ostream& os, const std::string& comment, const std::string& rule, - const cmNinjaDeps& outputs, const cmNinjaDeps& explicitDeps, - const cmNinjaDeps& implicitDeps, const cmNinjaDeps& orderOnlyDeps, - const cmNinjaVars& variables, const std::string& rspfile, int cmdLineLimit, - bool* usedResponseFile) + 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) { // Make sure there is a rule. if (rule.empty()) { @@ -204,6 +204,13 @@ void cmGlobalNinjaGenerator::WriteBuild( this->CombinedBuildOutputs.insert(EncodePath(*i)); } } + if (!implicitOuts.empty()) { + build += " |"; + for (cmNinjaDeps::const_iterator i = implicitOuts.begin(); + i != implicitOuts.end(); ++i) { + build += " " + EncodeIdent(EncodePath(*i), os); + } + } build += ":"; // Write the rule. @@ -244,7 +251,8 @@ void cmGlobalNinjaGenerator::WritePhonyBuild( const cmNinjaDeps& explicitDeps, const cmNinjaDeps& implicitDeps, const cmNinjaDeps& orderOnlyDeps, const cmNinjaVars& variables) { - this->WriteBuild(os, comment, "phony", outputs, explicitDeps, implicitDeps, + this->WriteBuild(os, comment, "phony", outputs, + /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, orderOnlyDeps, variables); } @@ -288,7 +296,8 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild( vars["depfile"] = depfile; } this->WriteBuild(*this->BuildFileStream, comment, "CUSTOM_COMMAND", outputs, - deps, cmNinjaDeps(), orderOnly, vars); + /*implicitOuts=*/cmNinjaDeps(), deps, cmNinjaDeps(), + orderOnly, vars); if (this->ComputingUnknownDependencies) { // we need to track every dependency that comes in, since we are trying @@ -330,7 +339,8 @@ void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input, cmNinjaVars vars; this->WriteBuild(*this->BuildFileStream, "", "COPY_OSX_CONTENT", outputs, - deps, cmNinjaDeps(), cmNinjaDeps(), cmNinjaVars()); + /*implicitOuts=*/cmNinjaDeps(), deps, cmNinjaDeps(), + cmNinjaDeps(), cmNinjaVars()); } void cmGlobalNinjaGenerator::WriteRule( @@ -1271,6 +1281,7 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os) this->WriteBuild(os, "Re-run CMake if any of its inputs changed.", "RERUN_CMAKE", /*outputs=*/cmNinjaDeps(1, ninjaBuildFile), + /*implicitOuts=*/cmNinjaDeps(), /*explicitDeps=*/cmNinjaDeps(), implicitDeps, /*orderOnlyDeps=*/cmNinjaDeps(), variables); @@ -1308,6 +1319,7 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) /*generator=*/false); WriteBuild(os, "Clean all the built files.", "CLEAN", /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("clean")), + /*implicitOuts=*/cmNinjaDeps(), /*explicitDeps=*/cmNinjaDeps(), /*implicitDeps=*/cmNinjaDeps(), /*orderOnlyDeps=*/cmNinjaDeps(), @@ -1327,6 +1339,7 @@ void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) /*generator=*/false); WriteBuild(os, "Print all primary targets available.", "HELP", /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("help")), + /*implicitOuts=*/cmNinjaDeps(), /*explicitDeps=*/cmNinjaDeps(), /*implicitDeps=*/cmNinjaDeps(), /*orderOnlyDeps=*/cmNinjaDeps(), diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index a0fad644b..d8eddd012 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -106,6 +106,7 @@ public: */ 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, diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx index f87a7883d..dbd84cb2b 100644 --- a/Source/cmNinjaNormalTargetGenerator.cxx +++ b/Source/cmNinjaNormalTargetGenerator.cxx @@ -691,7 +691,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() // Write the build statement for this target. bool usedResponseFile = false; globalGen.WriteBuild(this->GetBuildFileStream(), comment.str(), - this->LanguageLinkerRule(), outputs, explicitDeps, + this->LanguageLinkerRule(), outputs, + /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, orderOnlyDeps, vars, rspfile, commandLineLengthLimit, &usedResponseFile); this->WriteLinkRule(usedResponseFile); @@ -702,7 +703,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() this->GetBuildFileStream(), "Create executable symlink " + targetOutput, "CMAKE_SYMLINK_EXECUTABLE", cmNinjaDeps(1, targetOutput), - cmNinjaDeps(1, targetOutputReal), emptyDeps, emptyDeps, symlinkVars); + /*implicitOuts=*/cmNinjaDeps(), cmNinjaDeps(1, targetOutputReal), + emptyDeps, emptyDeps, symlinkVars); } else { cmNinjaDeps symlinks; std::string const soName = @@ -717,7 +719,8 @@ void cmNinjaNormalTargetGenerator::WriteLinkStatement() symlinks.push_back(targetOutput); globalGen.WriteBuild( this->GetBuildFileStream(), "Create library symlink " + targetOutput, - "CMAKE_SYMLINK_LIBRARY", symlinks, cmNinjaDeps(1, targetOutputReal), + "CMAKE_SYMLINK_LIBRARY", symlinks, + /*implicitOuts=*/cmNinjaDeps(), cmNinjaDeps(1, targetOutputReal), emptyDeps, emptyDeps, symlinkVars); } } diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 6ac59d576..fb09bfe25 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -607,8 +607,9 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement( std::string const rspfile = objectFileName + ".rsp"; this->GetGlobalGenerator()->WriteBuild( - this->GetBuildFileStream(), comment, rule, outputs, explicitDeps, - implicitDeps, orderOnlyDeps, vars, rspfile, commandLineLengthLimit); + this->GetBuildFileStream(), comment, rule, outputs, + /*implicitOuts=*/cmNinjaDeps(), explicitDeps, implicitDeps, orderOnlyDeps, + vars, rspfile, commandLineLengthLimit); if (const char* objectOutputs = source->GetProperty("OBJECT_OUTPUTS")) { std::vector outputList;