cmNinjaTargetGenerator: Fix scan rule PREPROCESSED_SOURCE placeholder

When running the module dependencies scan tool for for a language that
does not compile the preprocessed output, we do not actually put the
preprocessed output in the build graph.  However, the value of
`CMAKE_EXPERIMENTAL_<LANG>_SCANDEP_SOURCE` may reference the placeholder
for the preprocessed source.  Populate the placeholder to keep the file
out of the way.  In particular, do not clobber the `.ddi` file.
This commit is contained in:
Brad King 2021-06-14 15:15:39 -04:00
parent 1dd9c4ab6f
commit 312ced6547

View File

@ -536,7 +536,7 @@ std::string GetScanCommand(const std::string& cmakeCmd, const std::string& tdi,
// Helper function to create dependency scanning rule that may or may
// not perform explicit preprocessing too.
cmNinjaRule GetScanRule(
const std::string& ruleName,
std::string const& ruleName, std::string const& ppFileName,
cmRulePlaceholderExpander::RuleVariables const& vars,
const std::string& responseFlag, const std::string& flags,
cmRulePlaceholderExpander* const rulePlaceholderExpander,
@ -553,7 +553,7 @@ cmNinjaRule GetScanRule(
scanVars.CMTargetType = vars.CMTargetType;
scanVars.Language = vars.Language;
scanVars.Object = "$OBJ_FILE";
scanVars.PreprocessedSource = "$out";
scanVars.PreprocessedSource = ppFileName.c_str();
scanVars.DynDepFile = "$DYNDEP_INTERMEDIATE_FILE";
scanVars.DependencyFile = rule.DepFile.c_str();
scanVars.DependencyTarget = "$out";
@ -653,8 +653,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
{
std::vector<std::string> scanCommands;
std::string scanRuleName;
std::string ppFileName;
if (compilationPreprocesses) {
scanRuleName = this->LanguageScanRule(lang, config);
ppFileName = "$PREPROCESSED_OUTPUT_FILE";
std::string const& scanCommand = mf->GetRequiredDefinition(
cmStrCat("CMAKE_EXPERIMENTAL_", lang, "_SCANDEP_SOURCE"));
cmExpandList(scanCommand, scanCommands);
@ -663,6 +665,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
}
} else {
scanRuleName = this->LanguagePreprocessAndScanRule(lang, config);
ppFileName = "$out";
std::string const& ppCommmand = mf->GetRequiredDefinition(
cmStrCat("CMAKE_", lang, "_PREPROCESS_SOURCE"));
cmExpandList(ppCommmand, scanCommands);
@ -673,9 +676,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
"$DYNDEP_INTERMEDIATE_FILE"));
}
auto scanRule = GetScanRule(
scanRuleName, vars, responseFlag, flags, rulePlaceholderExpander.get(),
this->GetLocalGenerator(), std::move(scanCommands), config);
auto scanRule =
GetScanRule(scanRuleName, ppFileName, vars, responseFlag, flags,
rulePlaceholderExpander.get(), this->GetLocalGenerator(),
std::move(scanCommands), config);
scanRule.Comment =
cmStrCat("Rule for generating ", lang, " dependencies.");
@ -704,7 +708,7 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
GetScanCommand(cmakeCmd, tdi, lang, "$in", "$out"));
auto scanRule = GetScanRule(
scanRuleName, vars, "", flags, rulePlaceholderExpander.get(),
scanRuleName, "", vars, "", flags, rulePlaceholderExpander.get(),
this->GetLocalGenerator(), std::move(scanCommands), config);
// Write the rule for generating dependencies for the given language.
@ -1167,6 +1171,7 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
scanBuild.ImplicitOuts.push_back(ddiFile);
} else {
scanBuild.Outputs.push_back(ddiFile);
scanBuild.Variables["PREPROCESSED_OUTPUT_FILE"] = ppFileName;
}
// Scanning always uses a depfile for preprocessor dependencies.
@ -1362,6 +1367,7 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
this->GetPreprocessedFilePath(source, config));
} else {
scanRuleName = this->LanguageScanRule(language, config);
ppFileName = cmStrCat(objectFileName, ".ddi.i");
}
cmNinjaBuild ppBuild = GetScanBuildStatement(