Ninja: Centralize path conversion in global generator (#15757)

In the Ninja generator we run all build rules from the top of the build
tree rather than changing into each subdirectory.  Therefore we convert
all paths relative to the HOME_OUTPUT directory.  However, the Convert
method on cmLocalGenerator restricts relative path conversions to avoid
leaving the build tree with a "../" sequence.  Therefore conversions
performed for "subdirectories" that are outside the top of the build
tree always use full paths while conversions performed for
subdirectories that are inside the top of the build tree may use
relative paths to refer to the same files.

Since Ninja always runs rules from the top of the build tree we should
convert them using only the top-level cmLocalGenerator in order to
remain consistent.  Also extend the test suite with a case that fails
without this fix.
This commit is contained in:
Brad King
2015-09-25 13:26:44 -04:00
parent 993d064197
commit 6e2a4087f2
10 changed files with 51 additions and 47 deletions
+6 -12
View File
@@ -284,15 +284,6 @@ void cmLocalNinjaGenerator::WriteProcessedMakefile(std::ostream& os)
os << std::endl;
}
std::string cmLocalNinjaGenerator::ConvertToNinjaPath(const std::string& path)
{
std::string convPath = this->Convert(path, cmLocalGenerator::HOME_OUTPUT);
#ifdef _WIN32
cmSystemTools::ReplaceString(convPath, "/", "\\");
#endif
return convPath;
}
void
cmLocalNinjaGenerator
::AppendTargetOutputs(cmTarget* target, cmNinjaDeps& outputs)
@@ -316,7 +307,8 @@ void cmLocalNinjaGenerator::AppendCustomCommandDeps(
i != deps.end(); ++i) {
std::string dep;
if (this->GetRealDependency(*i, this->GetConfigName(), dep))
ninjaDeps.push_back(ConvertToNinjaPath(dep));
ninjaDeps.push_back(
this->GetGlobalNinjaGenerator()->ConvertToNinjaPath(dep));
}
}
@@ -413,9 +405,11 @@ cmLocalNinjaGenerator::WriteCustomCommandBuildStatement(
at us. How to know which ExternalProject step actually provides it?
#endif
std::transform(outputs.begin(), outputs.end(),
ninjaOutputs.begin(), MapToNinjaPath());
ninjaOutputs.begin(),
this->GetGlobalNinjaGenerator()->MapToNinjaPath());
std::transform(byproducts.begin(), byproducts.end(),
ninjaOutputs.begin() + outputs.size(), MapToNinjaPath());
ninjaOutputs.begin() + outputs.size(),
this->GetGlobalNinjaGenerator()->MapToNinjaPath());
this->AppendCustomCommandDeps(ccg, ninjaDeps);
for (cmNinjaDeps::iterator i = ninjaOutputs.begin(); i != ninjaOutputs.end();