1
0
mirror of https://github.com/Kitware/CMake.git synced 2025-10-15 20:46:37 +08:00

cmNinjaTargetGenerator: Simplify scan rule depfile selection

The depfile can always be the first output of the build statement
with a `.d` suffix added.  This approach easily avoids conflicts.
This commit is contained in:
Brad King
2020-11-06 11:26:42 -05:00
parent bff1871c39
commit 33a8e0bb09

View File

@@ -1064,13 +1064,12 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
const std::string& ppFileName, const std::string& ppFileName,
bool compilePP, bool compilePPWithDefines, bool compilePP, bool compilePPWithDefines,
cmNinjaBuild& objBuild, cmNinjaVars& vars, cmNinjaBuild& objBuild, cmNinjaVars& vars,
const std::string& depFileName, const std::string& objectFileName,
const std::string& objectFileName) cmLocalGenerator* lg)
{ {
cmNinjaBuild scanBuild(ruleName); cmNinjaBuild scanBuild(ruleName);
if (!ppFileName.empty()) { if (!ppFileName.empty()) {
scanBuild.Outputs.push_back(ppFileName);
scanBuild.RspFile = cmStrCat(ppFileName, ".rsp"); scanBuild.RspFile = cmStrCat(ppFileName, ".rsp");
} else { } else {
scanBuild.RspFile = "$out.rsp"; scanBuild.RspFile = "$out.rsp";
@@ -1109,26 +1108,32 @@ cmNinjaBuild GetScanBuildStatement(const std::string& ruleName,
// directive. // directive.
scanBuild.Variables["INCLUDES"] = vars["INCLUDES"]; scanBuild.Variables["INCLUDES"] = vars["INCLUDES"];
// Explicit preprocessing always uses a depfile. // Tell dependency scanner the object file that will result from
scanBuild.Variables["DEP_FILE"] = depFileName; // compiling the source.
scanBuild.Variables["OBJ_FILE"] = objectFileName;
// Tell dependency scanner where to store dyndep intermediate results.
std::string const& ddiFile = cmStrCat(objectFileName, ".ddi");
scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
// Outputs of the scan/preprocessor build statement.
if (!ppFileName.empty()) {
scanBuild.Outputs.push_back(ppFileName);
scanBuild.ImplicitOuts.push_back(ddiFile);
} else {
scanBuild.Outputs.push_back(ddiFile);
}
// Scanning always uses a depfile for preprocessor dependencies.
std::string const& depFileName = cmStrCat(scanBuild.Outputs.front(), ".d");
scanBuild.Variables["DEP_FILE"] =
lg->ConvertToOutputFormat(depFileName, cmOutputConverter::SHELL);
if (compilePP) { if (compilePP) {
// The actual compilation does not need a depfile because it // The actual compilation does not need a depfile because it
// depends on the already-preprocessed source. // depends on the already-preprocessed source.
vars.erase("DEP_FILE"); vars.erase("DEP_FILE");
} }
// Tell dependency scanner the object file that will result from
// compiling the source.
scanBuild.Variables["OBJ_FILE"] = objectFileName;
// Tell dependency scanner where to store dyndep intermediate results.
std::string const ddiFile = cmStrCat(objectFileName, ".ddi");
if (ppFileName.empty()) {
scanBuild.Outputs.push_back(ddiFile);
} else {
scanBuild.Variables["DYNDEP_INTERMEDIATE_FILE"] = ddiFile;
scanBuild.ImplicitOuts.push_back(ddiFile);
}
return scanBuild; return scanBuild;
} }
} }
@@ -1289,22 +1294,19 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
bool const compilePPWithDefines = bool const compilePPWithDefines =
compilePP && this->CompileWithDefines(language); compilePP && this->CompileWithDefines(language);
std::string const ppFileName = compilePP std::string scanRuleName;
? this->ConvertToNinjaPath(this->GetPreprocessedFilePath(source, config)) std::string ppFileName;
: ""; if (compilePP) {
scanRuleName = this->LanguagePreprocessAndScanRule(language, config);
std::string const buildName = compilePP ppFileName = this->ConvertToNinjaPath(
? this->LanguagePreprocessAndScanRule(language, config) this->GetPreprocessedFilePath(source, config));
: this->LanguageScanRule(language, config); } else {
scanRuleName = this->LanguageScanRule(language, config);
const auto depExtension = compilePP ? ".pp.d" : ".d"; }
const std::string depFileName =
this->GetLocalGenerator()->ConvertToOutputFormat(
cmStrCat(objectFileName, depExtension), cmOutputConverter::SHELL);
cmNinjaBuild ppBuild = GetScanBuildStatement( cmNinjaBuild ppBuild = GetScanBuildStatement(
buildName, ppFileName, compilePP, compilePPWithDefines, objBuild, vars, scanRuleName, ppFileName, compilePP, compilePPWithDefines, objBuild,
depFileName, objectFileName); vars, objectFileName, this->LocalGenerator);
if (compilePP) { if (compilePP) {
// In case compilation requires flags that are incompatible with // In case compilation requires flags that are incompatible with