Ninja: Use cmNinjaRule as sole parameter in the WriteRule and AddRule methods

Instead of passing multiple strings to the `WriteRule` and `AddRule` methods
of `cmGlobalNinjaGenerator`, pass only a `cmNinjaRule` instance reference,
that is set up beforehand.

Adapt calls to `WriteRule` and `AddRule` in multiple places.
This commit is contained in:
Sebastian Holtermann
2019-05-29 13:04:52 +02:00
parent 6a23fbce47
commit 6136ab5e17
4 changed files with 200 additions and 286 deletions

View File

@@ -238,14 +238,11 @@ void cmGlobalNinjaGenerator::WritePhonyBuild(
void cmGlobalNinjaGenerator::AddCustomCommandRule()
{
this->AddRule("CUSTOM_COMMAND", "$COMMAND", "$DESC",
"Rule for running custom commands.",
/*depfile*/ "",
/*deptype*/ "",
/*rspfile*/ "",
/*rspcontent*/ "",
/*restat*/ "", // bound on each build statement as needed
/*generator*/ false);
cmNinjaRule rule("CUSTOM_COMMAND");
rule.Command = "$COMMAND";
rule.Description = "$DESC";
rule.Comment = "Rule for running custom commands.";
this->AddRule(rule);
}
void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
@@ -293,15 +290,11 @@ void cmGlobalNinjaGenerator::WriteCustomCommandBuild(
void cmGlobalNinjaGenerator::AddMacOSXContentRule()
{
this->AddRule("COPY_OSX_CONTENT", CMakeCmd() + " -E copy $in $out",
"Copying OS X Content $out",
"Rule for copying OS X bundle content file.",
/*depfile*/ "",
/*deptype*/ "",
/*rspfile*/ "",
/*rspcontent*/ "",
/*restat*/ "",
/*generator*/ false);
cmNinjaRule rule("COPY_OSX_CONTENT");
rule.Command = CMakeCmd() + " -E copy $in $out";
rule.Description = "Copying OS X Content $out";
rule.Comment = "Rule for copying OS X bundle content file.";
this->AddRule(rule);
}
void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input,
@@ -320,40 +313,36 @@ void cmGlobalNinjaGenerator::WriteMacOSXContentBuild(const std::string& input,
cmNinjaDeps(), cmNinjaVars());
}
void cmGlobalNinjaGenerator::WriteRule(
std::ostream& os, const std::string& name, const std::string& command,
const std::string& description, const std::string& comment,
const std::string& depfile, const std::string& deptype,
const std::string& rspfile, const std::string& rspcontent,
const std::string& restat, bool generator)
void cmGlobalNinjaGenerator::WriteRule(std::ostream& os,
cmNinjaRule const& rule)
{
// -- Parameter checks
// Make sure the rule has a name.
if (name.empty()) {
if (rule.Name.empty()) {
cmSystemTools::Error("No name given for WriteRule! called with comment: " +
comment);
rule.Comment);
return;
}
// Make sure a command is given.
if (command.empty()) {
if (rule.Command.empty()) {
cmSystemTools::Error(
"No command given for WriteRule! called with comment: " + comment);
"No command given for WriteRule! called with comment: " + rule.Comment);
return;
}
// Make sure response file content is given
if (!rspfile.empty() && rspcontent.empty()) {
if (!rule.RspFile.empty() && rule.RspContent.empty()) {
cmSystemTools::Error("rspfile but no rspfile_content given for WriteRule! "
"called with comment: " +
comment);
rule.Comment);
return;
}
// -- Write rule
// Write rule intro
cmGlobalNinjaGenerator::WriteComment(os, comment);
os << "rule " << name << '\n';
cmGlobalNinjaGenerator::WriteComment(os, rule.Comment);
os << "rule " << rule.Name << '\n';
// Write rule key/value pairs
auto writeKV = [&os](const char* key, std::string const& value) {
@@ -363,16 +352,16 @@ void cmGlobalNinjaGenerator::WriteRule(
}
};
writeKV("depfile", depfile);
writeKV("deps", deptype);
writeKV("command", command);
writeKV("description", description);
if (!rspfile.empty()) {
writeKV("rspfile", rspfile);
writeKV("rspfile_content", rspcontent);
writeKV("depfile", rule.DepFile);
writeKV("deps", rule.DepType);
writeKV("command", rule.Command);
writeKV("description", rule.Description);
if (!rule.RspFile.empty()) {
writeKV("rspfile", rule.RspFile);
writeKV("rspfile_content", rule.RspContent);
}
writeKV("restat", restat);
if (generator) {
writeKV("restat", rule.Restat);
if (rule.Generator) {
writeKV("generator", "1");
}
@@ -690,23 +679,16 @@ cmGlobalNinjaGenerator::GenerateBuildCommand(
// Non-virtual public methods.
void cmGlobalNinjaGenerator::AddRule(
const std::string& name, const std::string& command,
const std::string& description, const std::string& comment,
const std::string& depfile, const std::string& deptype,
const std::string& rspfile, const std::string& rspcontent,
const std::string& restat, bool generator)
void cmGlobalNinjaGenerator::AddRule(cmNinjaRule const& rule)
{
// Do not add the same rule twice.
if (!this->Rules.insert(name).second) {
if (!this->Rules.insert(rule.Name).second) {
return;
}
// Store command length
this->RuleCmdLength[name] = static_cast<int>(command.size());
this->RuleCmdLength[rule.Name] = static_cast<int>(rule.Command.size());
// Write rule
cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, name, command,
description, comment, depfile, deptype,
rspfile, rspcontent, restat, generator);
cmGlobalNinjaGenerator::WriteRule(*this->RulesFileStream, rule);
}
bool cmGlobalNinjaGenerator::HasRule(const std::string& name)
@@ -1322,21 +1304,18 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmLocalGenerator* lg = this->LocalGenerators[0];
{
std::string cmd = CMakeCmd();
cmd += " -S";
cmd += lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL);
cmd += " -B";
cmd += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
cmOutputConverter::SHELL);
WriteRule(*this->RulesFileStream, "RERUN_CMAKE", cmd,
"Re-running CMake...", "Rule for re-running cmake.",
/*depfile=*/"",
/*deptype=*/"",
/*rspfile=*/"",
/*rspcontent*/ "",
/*restat=*/"",
/*generator=*/true);
cmNinjaRule rule("RERUN_CMAKE");
rule.Command = CMakeCmd();
rule.Command += " -S";
rule.Command += lg->ConvertToOutputFormat(lg->GetSourceDirectory(),
cmOutputConverter::SHELL);
rule.Command += " -B";
rule.Command += lg->ConvertToOutputFormat(lg->GetBinaryDirectory(),
cmOutputConverter::SHELL);
rule.Description = "Re-running CMake...";
rule.Comment = "Rule for re-running cmake.";
rule.Generator = true;
WriteRule(*this->RulesFileStream, rule);
}
cmNinjaDeps implicitDeps;
@@ -1358,20 +1337,15 @@ void cmGlobalNinjaGenerator::WriteTargetRebuildManifest(std::ostream& os)
cmake* cm = this->GetCMakeInstance();
if (this->SupportsManifestRestat() && cm->DoWriteGlobVerifyTarget()) {
{
std::string cmd = CMakeCmd();
cmd += " -P ";
cmd += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
cmOutputConverter::SHELL);
WriteRule(*this->RulesFileStream, "VERIFY_GLOBS", cmd,
"Re-checking globbed directories...",
"Rule for re-checking globbed directories.",
/*depfile=*/"",
/*deptype=*/"",
/*rspfile=*/"",
/*rspcontent*/ "",
/*restat=*/"",
/*generator=*/true);
cmNinjaRule rule("VERIFY_GLOBS");
rule.Command = CMakeCmd();
rule.Command += " -P ";
rule.Command += lg->ConvertToOutputFormat(cm->GetGlobVerifyScript(),
cmOutputConverter::SHELL);
rule.Description = "Re-checking globbed directories...";
rule.Comment = "Rule for re-checking globbed directories.";
rule.Generator = true;
this->WriteRule(*this->RulesFileStream, rule);
}
std::string verifyForce = cm->GetGlobVerifyScript() + "_force";
@@ -1507,19 +1481,14 @@ bool cmGlobalNinjaGenerator::WriteTargetCleanAdditional(std::ostream& os)
// 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);
cmNinjaRule rule("CLEAN_ADDITIONAL");
rule.Command = CMakeCmd();
rule.Command += " -P ";
rule.Command += lgr->ConvertToOutputFormat(
this->NinjaOutputPath(cleanScriptRel), cmOutputConverter::SHELL);
rule.Description = "Cleaning additional files...";
rule.Comment = "Rule for cleaning additional files.";
WriteRule(*this->RulesFileStream, rule);
}
// Write build
@@ -1546,15 +1515,13 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
// -- Default clean target
// Write rule
WriteRule(*this->RulesFileStream, "CLEAN", NinjaCmd() + " -t clean",
"Cleaning all built files...",
"Rule for cleaning all built files.",
/*depfile=*/"",
/*deptype=*/"",
/*rspfile=*/"",
/*rspcontent*/ "",
/*restat=*/"",
/*generator=*/false);
{
cmNinjaRule rule("CLEAN");
rule.Command = NinjaCmd() + " -t clean";
rule.Description = "Cleaning all built files...";
rule.Comment = "Rule for cleaning all built files.";
WriteRule(*this->RulesFileStream, rule);
}
// Write build
{
@@ -1577,15 +1544,13 @@ void cmGlobalNinjaGenerator::WriteTargetClean(std::ostream& os)
void cmGlobalNinjaGenerator::WriteTargetHelp(std::ostream& os)
{
WriteRule(*this->RulesFileStream, "HELP", NinjaCmd() + " -t targets",
"All primary targets available:",
"Rule for printing all primary targets available.",
/*depfile=*/"",
/*deptype=*/"",
/*rspfile=*/"",
/*rspcontent*/ "",
/*restat=*/"",
/*generator=*/false);
{
cmNinjaRule rule("HELP");
rule.Command = NinjaCmd() + " -t targets";
rule.Description = "All primary targets available:";
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(),

View File

@@ -138,18 +138,10 @@ public:
const std::string& output);
/**
* Write a rule statement named @a name to @a os with the @a comment,
* the mandatory @a command, the @a depfile and the @a description.
* It also writes the variables bound to this rule statement.
* Write a rule statement to @a os.
* @warning no escaping of any kind is done here.
*/
static void WriteRule(std::ostream& os, const std::string& name,
const std::string& command,
const std::string& description,
const std::string& comment, const std::string& depfile,
const std::string& deptype, const std::string& rspfile,
const std::string& rspcontent,
const std::string& restat, bool generator);
static void WriteRule(std::ostream& os, cmNinjaRule const& rule);
/**
* Write a variable named @a name to @a os with value @a value and an
@@ -273,11 +265,7 @@ public:
* Call WriteRule() behind the scene but perform some check before like:
* - Do not add twice the same rule.
*/
void AddRule(const std::string& name, const std::string& command,
const std::string& description, const std::string& comment,
const std::string& depfile, const std::string& deptype,
const std::string& rspfile, const std::string& rspcontent,
const std::string& restat, bool generator);
void AddRule(cmNinjaRule const& rule);
bool HasRule(const std::string& name);

View File

@@ -162,13 +162,8 @@ struct cmNinjaRemoveNoOpCommands
void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
{
cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType();
std::string ruleName = this->LanguageLinkerDeviceRule();
// Select whether to use a response file for objects.
std::string rspfile;
std::string rspcontent;
if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
cmNinjaRule rule(this->LanguageLinkerDeviceRule());
if (!this->GetGlobalGenerator()->HasRule(rule.Name)) {
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
@@ -192,16 +187,16 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
} else {
responseFlag = "@";
}
rspfile = "$RSP_FILE";
responseFlag += rspfile;
rule.RspFile = "$RSP_FILE";
responseFlag += rule.RspFile;
// build response file content
if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
rspcontent = "$in";
rule.RspContent = "$in";
} else {
rspcontent = "$in_newline";
rule.RspContent = "$in_newline";
}
rspcontent += " $LINK_LIBRARIES";
rule.RspContent += " $LINK_LIBRARIES";
vars.Objects = responseFlag.c_str();
vars.LinkLibraries = "";
}
@@ -220,7 +215,7 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
vars.Manifests = "$MANIFESTS";
std::string langFlags;
if (targetType != cmStateEnums::EXECUTABLE) {
if (this->GetGeneratorTarget()->GetType() != cmStateEnums::EXECUTABLE) {
langFlags += "$LANGUAGE_COMPILE_FLAGS $ARCH_FLAGS";
vars.LanguageCompileFlags = langFlags.c_str();
}
@@ -247,39 +242,35 @@ void cmNinjaNormalTargetGenerator::WriteDeviceLinkRule(bool useResponseFile)
// If there is no ranlib the command will be ":". Skip it.
cmEraseIf(linkCmds, cmNinjaRemoveNoOpCommands());
std::string linkCmd =
this->GetLocalGenerator()->BuildCommandLine(linkCmds);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
std::ostringstream comment;
comment << "Rule for linking " << this->TargetLinkLanguage << " "
<< this->GetVisibleTypeName() << ".";
std::ostringstream description;
description << "Linking " << this->TargetLinkLanguage << " "
<< this->GetVisibleTypeName() << " $TARGET_FILE";
this->GetGlobalGenerator()->AddRule(ruleName, linkCmd, description.str(),
comment.str(),
/*depfile*/ "",
/*deptype*/ "", rspfile, rspcontent,
/*restat*/ "$RESTAT",
/*generator*/ false);
rule.Comment = "Rule for linking ";
rule.Comment += this->TargetLinkLanguage;
rule.Comment += " ";
rule.Comment += this->GetVisibleTypeName();
rule.Comment += ".";
rule.Description = "Linking ";
rule.Description += this->TargetLinkLanguage;
rule.Description += " ";
rule.Description += this->GetVisibleTypeName();
rule.Description += " $TARGET_FILE";
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
}
void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
{
cmStateEnums::TargetType targetType = this->GetGeneratorTarget()->GetType();
std::string ruleName = this->LanguageLinkerRule();
// Select whether to use a response file for objects.
std::string rspfile;
std::string rspcontent;
if (!this->GetGlobalGenerator()->HasRule(ruleName)) {
std::string linkRuleName = this->LanguageLinkerRule();
if (!this->GetGlobalGenerator()->HasRule(linkRuleName)) {
cmNinjaRule rule(std::move(linkRuleName));
cmRulePlaceholderExpander::RuleVariables vars;
vars.CMTargetName = this->GetGeneratorTarget()->GetName().c_str();
vars.CMTargetType =
cmState::GetTargetTypeName(this->GetGeneratorTarget()->GetType());
vars.CMTargetType = cmState::GetTargetTypeName(targetType);
vars.Language = this->TargetLinkLanguage.c_str();
@@ -311,16 +302,16 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
} else {
responseFlag = "@";
}
rspfile = "$RSP_FILE";
responseFlag += rspfile;
rule.RspFile = "$RSP_FILE";
responseFlag += rule.RspFile;
// build response file content
if (this->GetGlobalGenerator()->IsGCCOnWindows()) {
rspcontent = "$in";
rule.RspContent = "$in";
} else {
rspcontent = "$in_newline";
rule.RspContent = "$in_newline";
}
rspcontent += " $LINK_PATH $LINK_LIBRARIES";
rule.RspContent += " $LINK_PATH $LINK_LIBRARIES";
if (this->TargetLinkLanguage == "Swift") {
vars.SwiftSources = responseFlag.c_str();
} else {
@@ -389,22 +380,21 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
linkCmds.insert(linkCmds.begin(), "$PRE_LINK");
linkCmds.emplace_back("$POST_BUILD");
std::string linkCmd =
this->GetLocalGenerator()->BuildCommandLine(linkCmds);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(linkCmds);
// Write the linker rule with response file if needed.
std::ostringstream comment;
comment << "Rule for linking " << this->TargetLinkLanguage << " "
<< this->GetVisibleTypeName() << ".";
std::ostringstream description;
description << "Linking " << this->TargetLinkLanguage << " "
<< this->GetVisibleTypeName() << " $TARGET_FILE";
this->GetGlobalGenerator()->AddRule(ruleName, linkCmd, description.str(),
comment.str(),
/*depfile*/ "",
/*deptype*/ "", rspfile, rspcontent,
/*restat*/ "$RESTAT",
/*generator*/ false);
rule.Comment = "Rule for linking ";
rule.Comment += this->TargetLinkLanguage;
rule.Comment += " ";
rule.Comment += this->GetVisibleTypeName();
rule.Comment += ".";
rule.Description = "Linking ";
rule.Description += this->TargetLinkLanguage;
rule.Description += " ";
rule.Description += this->GetVisibleTypeName();
rule.Description += " $TARGET_FILE";
rule.Restat = "$RESTAT";
this->GetGlobalGenerator()->AddRule(rule);
}
if (this->TargetNames.Output != this->TargetNames.Real &&
@@ -413,41 +403,28 @@ void cmNinjaNormalTargetGenerator::WriteLinkRule(bool useResponseFile)
this->GetLocalGenerator()->ConvertToOutputFormat(
cmSystemTools::GetCMakeCommand(), cmOutputConverter::SHELL);
if (targetType == cmStateEnums::EXECUTABLE) {
std::vector<std::string> commandLines;
commandLines.push_back(cmakeCommand +
" -E cmake_symlink_executable $in $out");
commandLines.emplace_back("$POST_BUILD");
this->GetGlobalGenerator()->AddRule(
"CMAKE_SYMLINK_EXECUTABLE",
this->GetLocalGenerator()->BuildCommandLine(commandLines),
"Creating executable symlink $out",
"Rule for creating "
"executable symlink.",
/*depfile*/ "",
/*deptype*/ "",
/*rspfile*/ "",
/*rspcontent*/ "",
/*restat*/ "",
/*generator*/ false);
cmNinjaRule rule("CMAKE_SYMLINK_EXECUTABLE");
{
std::vector<std::string> cmd;
cmd.push_back(cmakeCommand + " -E cmake_symlink_executable $in $out");
cmd.emplace_back("$POST_BUILD");
rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd);
}
rule.Description = "Creating executable symlink $out";
rule.Comment = "Rule for creating executable symlink.";
this->GetGlobalGenerator()->AddRule(rule);
} else {
std::vector<std::string> commandLines;
commandLines.push_back(cmakeCommand +
" -E cmake_symlink_library $in $SONAME $out");
commandLines.emplace_back("$POST_BUILD");
this->GetGlobalGenerator()->AddRule(
"CMAKE_SYMLINK_LIBRARY",
this->GetLocalGenerator()->BuildCommandLine(commandLines),
"Creating library symlink $out",
"Rule for creating "
"library symlink.",
/*depfile*/ "",
/*deptype*/ "",
/*rspfile*/ "",
/*rspcontent*/ "",
/*restat*/ "",
/*generator*/ false);
cmNinjaRule rule("CMAKE_SYMLINK_LIBRARY");
{
std::vector<std::string> cmd;
cmd.push_back(cmakeCommand +
" -E cmake_symlink_library $in $SONAME $out");
cmd.emplace_back("$POST_BUILD");
rule.Command = this->GetLocalGenerator()->BuildCommandLine(cmd);
}
rule.Description = "Creating library symlink $out";
rule.Comment = "Rule for creating library symlink.";
this->GetGlobalGenerator()->AddRule(rule);
}
}
}

View File

@@ -495,9 +495,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cmSystemTools::GetCMakeCommand(), cmLocalGenerator::SHELL);
if (explicitPP) {
cmNinjaRule rule(this->LanguagePreprocessRule(lang));
// Explicit preprocessing always uses a depfile.
std::string const ppDeptype; // no deps= for multiple outputs
std::string const ppDepfile = "$DEP_FILE";
rule.DepType = ""; // no deps= for multiple outputs
rule.DepFile = "$DEP_FILE";
cmRulePlaceholderExpander::RuleVariables ppVars;
ppVars.CMTargetName = vars.CMTargetName;
@@ -505,7 +506,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
ppVars.Language = vars.Language;
ppVars.Object = "$out"; // for RULE_LAUNCH_COMPILE
ppVars.PreprocessedSource = "$out";
ppVars.DependencyFile = ppDepfile.c_str();
ppVars.DependencyFile = rule.DepFile.c_str();
// Preprocessing uses the original source,
// compilation uses preprocessed output.
@@ -524,17 +525,15 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
ppVars.Includes = vars.Includes;
// If using a response file, move defines, includes, and flags into it.
std::string ppRspFile;
std::string ppRspContent;
if (!responseFlag.empty()) {
ppRspFile = "$RSP_FILE";
ppRspContent = " ";
ppRspContent += ppVars.Defines;
ppRspContent += " ";
ppRspContent += ppVars.Includes;
ppRspContent += " ";
ppRspContent += ppFlags;
ppFlags = responseFlag + ppRspFile;
rule.RspFile = "$RSP_FILE";
rule.RspContent = " ";
rule.RspContent += ppVars.Defines;
rule.RspContent += " ";
rule.RspContent += ppVars.Includes;
rule.RspContent += " ";
rule.RspContent += ppFlags;
ppFlags = responseFlag + rule.RspFile;
ppVars.Defines = "";
ppVars.Includes = "";
}
@@ -570,31 +569,25 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
}
ppCmds.emplace_back(std::move(ccmd));
}
std::string const ppCmdLine =
this->GetLocalGenerator()->BuildCommandLine(ppCmds);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(ppCmds);
// Write the rule for preprocessing file of the given language.
std::string ppComment = "Rule for preprocessing ";
ppComment += lang;
ppComment += " files.";
std::string ppDesc = "Building ";
ppDesc += lang;
ppDesc += " preprocessed $out";
this->GetGlobalGenerator()->AddRule(
this->LanguagePreprocessRule(lang), ppCmdLine, ppDesc, ppComment,
ppDepfile, ppDeptype, ppRspFile, ppRspContent,
/*restat*/ "",
/*generator*/ false);
rule.Comment = "Rule for preprocessing ";
rule.Comment += lang;
rule.Comment += " files.";
rule.Description = "Building ";
rule.Description += lang;
rule.Description += " preprocessed $out";
this->GetGlobalGenerator()->AddRule(rule);
}
if (needDyndep) {
// Write the rule for ninja dyndep file generation.
cmNinjaRule rule(this->LanguageDyndepRule(lang));
// Command line length is almost always limited -> use response file for
// dyndep rules
std::string ddRspFile = "$out.rsp";
std::string ddRspContent = "$in";
std::string ddCmdLine;
rule.RspFile = "$out.rsp";
rule.RspContent = "$in";
// Run CMake dependency scanner on the source file (using the preprocessed
// source if that was performed).
@@ -608,53 +601,49 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
ccmd += lang;
ccmd += " --dd=$out ";
ccmd += "@";
ccmd += ddRspFile;
ccmd += rule.RspFile;
ddCmds.emplace_back(std::move(ccmd));
}
ddCmdLine = this->GetLocalGenerator()->BuildCommandLine(ddCmds);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(ddCmds);
}
std::string ddComment = "Rule to generate ninja dyndep files for ";
ddComment += lang;
ddComment += ".";
std::string ddDesc = "Generating ";
ddDesc += lang;
ddDesc += " dyndep file $out";
this->GetGlobalGenerator()->AddRule(this->LanguageDyndepRule(lang),
ddCmdLine, ddDesc, ddComment,
/*depfile*/ "",
/*deps*/ "", ddRspFile, ddRspContent,
/*restat*/ "",
/*generator*/ false);
rule.Comment = "Rule to generate ninja dyndep files for ";
rule.Comment += lang;
rule.Comment += ".";
rule.Description = "Generating ";
rule.Description += lang;
rule.Description += " dyndep file $out";
this->GetGlobalGenerator()->AddRule(rule);
}
cmNinjaRule rule(this->LanguageCompilerRule(lang));
// If using a response file, move defines, includes, and flags into it.
std::string rspfile;
std::string rspcontent;
if (!responseFlag.empty()) {
rspfile = "$RSP_FILE";
rspcontent =
std::string(" ") + vars.Defines + " " + vars.Includes + " " + flags;
flags = responseFlag + rspfile;
rule.RspFile = "$RSP_FILE";
rule.RspContent = " ";
rule.RspContent += vars.Defines;
rule.RspContent += " ";
rule.RspContent += vars.Includes;
rule.RspContent += " ";
rule.RspContent += flags;
flags = responseFlag + rule.RspFile;
vars.Defines = "";
vars.Includes = "";
}
// Tell ninja dependency format so all deps can be loaded into a database
std::string deptype;
std::string depfile;
std::string cldeps;
if (explicitPP) {
// The explicit preprocessing step will handle dependency scanning.
} else if (this->NeedDepTypeMSVC(lang)) {
deptype = "msvc";
depfile.clear();
rule.DepType = "msvc";
rule.DepFile.clear();
flags += " /showIncludes";
} else if (mf->IsOn("CMAKE_NINJA_CMCLDEPS_" + lang)) {
// For the MS resource compiler we need cmcldeps, but skip dependencies
// for source-file try_compile cases because they are always fresh.
if (!mf->GetIsSourceFileTryCompile()) {
deptype = "gcc";
depfile = "$DEP_FILE";
rule.DepType = "gcc";
rule.DepFile = "$DEP_FILE";
const std::string cl = mf->GetDefinition("CMAKE_C_COMPILER")
? mf->GetSafeDefinition("CMAKE_C_COMPILER")
: mf->GetSafeDefinition("CMAKE_CXX_COMPILER");
@@ -665,8 +654,8 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
cldeps += "\" \"" + cl + "\" ";
}
} else {
deptype = "gcc";
depfile = "$DEP_FILE";
rule.DepType = "gcc";
rule.DepFile = "$DEP_FILE";
const std::string flagsName = "CMAKE_DEPFILE_FLAGS_" + lang;
std::string depfileFlags = mf->GetSafeDefinition(flagsName);
if (!depfileFlags.empty()) {
@@ -679,7 +668,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
}
vars.Flags = flags.c_str();
vars.DependencyFile = depfile.c_str();
vars.DependencyFile = rule.DepFile.c_str();
// Rule for compiling object file.
std::vector<std::string> compileCmds;
@@ -784,21 +773,16 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang)
vars);
}
std::string cmdLine =
this->GetLocalGenerator()->BuildCommandLine(compileCmds);
rule.Command = this->GetLocalGenerator()->BuildCommandLine(compileCmds);
// Write the rule for compiling file of the given language.
std::string comment = "Rule for compiling ";
comment += lang;
comment += " files.";
std::string description = "Building ";
description += lang;
description += " object $out";
this->GetGlobalGenerator()->AddRule(this->LanguageCompilerRule(lang),
cmdLine, description, comment, depfile,
deptype, rspfile, rspcontent,
/*restat*/ "",
/*generator*/ false);
rule.Comment = "Rule for compiling ";
rule.Comment += lang;
rule.Comment += " files.";
rule.Description = "Building ";
rule.Description += lang;
rule.Description += " object $out";
this->GetGlobalGenerator()->AddRule(rule);
}
void cmNinjaTargetGenerator::WriteObjectBuildStatements()