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.
This commit is contained in:
Sebastian Holtermann 2019-05-13 16:42:06 +02:00
parent d745df4b01
commit 7b23001f20
2 changed files with 104 additions and 7 deletions

View File

@ -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)

View File

@ -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<std::string> AdditionalCleanFiles;
};
#endif // ! cmGlobalNinjaGenerator_h