Ninja: Make cmcldeps depfile output more consistent with 'ninja -t msvc'
Ninja relies on the generator to produce paths that match up with the paths used in the build.ninja file, which are spelled with backslashes. Therefore, cmcldeps should canonicalize depfile paths to use backslashes and relativize paths to the build directory.
This commit is contained in:
parent
ffe79b582f
commit
6fa9d0ab40
|
@ -62,8 +62,8 @@ static std::string trimLeadingSpace(const std::string& cmdline) {
|
||||||
return cmdline.substr(i);
|
return cmdline.substr(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doEscape(std::string& str, const std::string& search,
|
static void replaceAll(std::string& str, const std::string& search,
|
||||||
const std::string& repl) {
|
const std::string& repl) {
|
||||||
std::string::size_type pos = 0;
|
std::string::size_type pos = 0;
|
||||||
while ((pos = str.find(search, pos)) != std::string::npos) {
|
while ((pos = str.find(search, pos)) != std::string::npos) {
|
||||||
str.replace(pos, search.size(), repl);
|
str.replace(pos, search.size(), repl);
|
||||||
|
@ -71,6 +71,10 @@ static void doEscape(std::string& str, const std::string& search,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool startsWith(const std::string& str, const std::string& what) {
|
||||||
|
return str.compare(0, what.size(), what) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Strips one argument from the cmdline and returns it. "surrounding quotes"
|
// Strips one argument from the cmdline and returns it. "surrounding quotes"
|
||||||
// are removed from the argument if there were any.
|
// are removed from the argument if there were any.
|
||||||
static std::string getArg(std::string& cmdline) {
|
static std::string getArg(std::string& cmdline) {
|
||||||
|
@ -117,6 +121,13 @@ static void parseCommandLine(LPTSTR wincmdline,
|
||||||
rest = trimLeadingSpace(cmdline);
|
rest = trimLeadingSpace(cmdline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Not all backslashes need to be escaped in a depfile, but it's easier that
|
||||||
|
// way. See the re2c grammar in ninja's source code for more info.
|
||||||
|
static void escapePath(std::string &path) {
|
||||||
|
replaceAll(path, "\\", "\\\\");
|
||||||
|
replaceAll(path, " ", "\\ ");
|
||||||
|
}
|
||||||
|
|
||||||
static void outputDepFile(const std::string& dfile, const std::string& objfile,
|
static void outputDepFile(const std::string& dfile, const std::string& objfile,
|
||||||
std::vector<std::string>& incs) {
|
std::vector<std::string>& incs) {
|
||||||
|
|
||||||
|
@ -132,16 +143,24 @@ static void outputDepFile(const std::string& dfile, const std::string& objfile,
|
||||||
// FIXME should this be fatal or not? delete obj? delete d?
|
// FIXME should this be fatal or not? delete obj? delete d?
|
||||||
if (!out)
|
if (!out)
|
||||||
return;
|
return;
|
||||||
|
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
|
||||||
|
replaceAll(cwd, "/", "\\");
|
||||||
|
cwd += "\\";
|
||||||
|
|
||||||
std::string tmp = objfile;
|
std::string tmp = objfile;
|
||||||
doEscape(tmp, " ", "\\ ");
|
escapePath(tmp);
|
||||||
fprintf(out, "%s: \\\n", tmp.c_str());
|
fprintf(out, "%s: \\\n", tmp.c_str());
|
||||||
|
|
||||||
std::vector<std::string>::iterator it = incs.begin();
|
std::vector<std::string>::iterator it = incs.begin();
|
||||||
for (; it != incs.end(); ++it) {
|
for (; it != incs.end(); ++it) {
|
||||||
tmp = *it;
|
tmp = *it;
|
||||||
doEscape(tmp, "\\", "/");
|
// The paths need to match the ones used to identify build artifacts in the
|
||||||
doEscape(tmp, " ", "\\ ");
|
// build.ninja file. Therefore we need to canonicalize the path to use
|
||||||
|
// backward slashes and relativize the path to the build directory.
|
||||||
|
replaceAll(tmp, "/", "\\");
|
||||||
|
if (startsWith(tmp, cwd))
|
||||||
|
tmp = tmp.substr(cwd.size());
|
||||||
|
escapePath(tmp);
|
||||||
fprintf(out, "%s \\\n", tmp.c_str());
|
fprintf(out, "%s \\\n", tmp.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,10 +169,6 @@ static void outputDepFile(const std::string& dfile, const std::string& objfile,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool startsWith(const std::string& str, const std::string& what) {
|
|
||||||
return str.compare(0, what.size(), what) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool contains(const std::string& str, const std::string& what) {
|
bool contains(const std::string& str, const std::string& what) {
|
||||||
return str.find(what) != std::string::npos;
|
return str.find(what) != std::string::npos;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue