From 7b23001f20440d6c631d9fd6df4ec0092efce4f5 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Mon, 13 May 2019 16:42:06 +0200 Subject: Ninja: Add support for additional clean files Additional clean files for the Ninja generator can be registered via the new method `cmGlobalNinjaGenerator::AddAdditionalCleanFile`. If there are additional clean files, a new rule `CLEAN_ADDITIONAL` and a new build target `CMakeFiles/clean.additional` get generated. The `clean` target will depend on `CMakeFiles/clean.additional`, if the target exists. --- Source/cmGlobalNinjaGenerator.cxx | 102 +++++++++++++++++++++++++++++++++++--- Source/cmGlobalNinjaGenerator.h | 9 ++++ 2 files changed, 104 insertions(+), 7 deletions(-) diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx index 1b973e0..5d4f6db 100644 --- a/Source/cmGlobalNinjaGenerator.cxx +++ b/Source/cmGlobalNinjaGenerator.cxx @@ -852,6 +852,11 @@ std::string const& cmGlobalNinjaGenerator::ConvertToNinjaPath( .first->second; } +void cmGlobalNinjaGenerator::AddAdditionalCleanFile(std::string fileName) +{ + this->AdditionalCleanFiles.emplace(std::move(fileName)); +} + void cmGlobalNinjaGenerator::AddCXXCompileCommand( const std::string& commandLine, const std::string& sourceFile) { @@ -1464,8 +1469,80 @@ bool cmGlobalNinjaGenerator::SupportsMultilineDepfile() const return this->NinjaSupportsMultilineDepfile; } +bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os) +{ + cmLocalGenerator* lgr = this->LocalGenerators.at(0); + std::string cleanScriptRel = "CMakeFiles/clean_additional.cmake"; + std::string cleanScriptAbs = lgr->GetBinaryDirectory(); + cleanScriptAbs += '/'; + cleanScriptAbs += cleanScriptRel; + + // Check if there are additional files to clean + if (this->AdditionalCleanFiles.empty()) { + // Remove cmake clean script file if it exists + cmSystemTools::RemoveFile(cleanScriptAbs); + return false; + } + + // Write cmake clean script file + { + cmGeneratedFileStream fout(cleanScriptAbs); + if (!fout) { + return false; + } + fout << "# Additional clean files\n\n"; + fout << "file(REMOVE_RECURSE\n"; + for (std::string const& acf : this->AdditionalCleanFiles) { + fout << " " + << cmOutputConverter::EscapeForCMake(ConvertToNinjaPath(acf)) + << '\n'; + } + fout << ")\n"; + } + // Register clean script file + lgr->GetMakefile()->AddCMakeOutputFile(cleanScriptAbs); + + // Write rule + { + std::string cmd = CMakeCmd(); + cmd += " -P "; + cmd += lgr->ConvertToOutputFormat(this->NinjaOutputPath(cleanScriptRel), + cmOutputConverter::SHELL); + WriteRule(*this->RulesFileStream, "CLEAN_ADDITIONAL", cmd, + "Cleaning additional files...", + "Rule for cleaning additional files.", + /*depfile=*/"", + /*deptype=*/"", + /*rspfile=*/"", + /*rspcontent*/ "", + /*restat=*/"", + /*generator=*/false); + } + + // Write build + { + cmNinjaDeps outputs; + outputs.emplace_back( + this->NinjaOutputPath(this->GetAdditionalCleanTargetName())); + WriteBuild(os, "Clean additional files.", "CLEAN_ADDITIONAL", + /*outputs=*/outputs, + /*implicitOuts=*/cmNinjaDeps(), + /*explicitDeps=*/cmNinjaDeps(), + /*implicitDeps=*/cmNinjaDeps(), + /*orderOnlyDeps=*/cmNinjaDeps(), + /*variables=*/cmNinjaVars()); + } + // Return success + return true; +} + void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) { + // -- Additional clean target + bool additionalFiles = WriteTargetCleanAdditional(os); + + // -- Default clean target + // Write rule WriteRule(*this->RulesFileStream, "CLEAN", NinjaCmd() + " -t clean", "Cleaning all built files...", "Rule for cleaning all built files.", @@ -1475,13 +1552,24 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os) /*rspcontent*/ "", /*restat=*/"", /*generator=*/false); - WriteBuild(os, "Clean all the built files.", "CLEAN", - /*outputs=*/cmNinjaDeps(1, this->NinjaOutputPath("clean")), - /*implicitOuts=*/cmNinjaDeps(), - /*explicitDeps=*/cmNinjaDeps(), - /*implicitDeps=*/cmNinjaDeps(), - /*orderOnlyDeps=*/cmNinjaDeps(), - /*variables=*/cmNinjaVars()); + + // Write build + { + cmNinjaDeps explicitDeps; + if (additionalFiles) { + explicitDeps.emplace_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()); + } } void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os) diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h index ffcea60..0f90b30 100644 --- a/Source/cmGlobalNinjaGenerator.h +++ b/Source/cmGlobalNinjaGenerator.h @@ -257,6 +257,13 @@ public: }; MapToNinjaPathImpl MapToNinjaPath() { return MapToNinjaPathImpl(this); } + // -- Additional clean files + void AddAdditionalCleanFile(std::string fileName); + const char* GetAdditionalCleanTargetName() const + { + return "CMakeFiles/clean.additional"; + } + void AddCXXCompileCommand(const std::string& commandLine, const std::string& sourceFile); @@ -398,6 +405,7 @@ private: void WriteBuiltinTargets(std::ostream& os); void WriteTargetAll(std::ostream& os); void WriteTargetRebuildManifest(std::ostream& os); + bool WriteTargetCleanAdditional(std::ostream& os); void WriteTargetClean(std::ostream& os); void WriteTargetHelp(std::ostream& os); @@ -470,6 +478,7 @@ private: std::string OutputPathPrefix; std::string TargetAll; std::string CMakeCacheFile; + std::set AdditionalCleanFiles; }; #endif // ! cmGlobalNinjaGenerator_h -- cgit v0.12