summaryrefslogtreecommitdiff
path: root/Source/cmcldeps.cxx
diff options
context:
space:
mode:
authorKévin THIERRY <kevin.thierry@open.eurogiciel.org>2014-12-23 09:30:24 +0100
committerKévin THIERRY <kevin.thierry@open.eurogiciel.org>2014-12-23 09:30:24 +0100
commit317dbdb79761ef65e45c7358cfc7571c6afa54ad (patch)
treed6e8d59029aea04ca4a0579fb1c19c3e493af78f /Source/cmcldeps.cxx
parent297c63fa65327491a2b50e521b661c5835a19fe4 (diff)
downloadcmake-317dbdb79761ef65e45c7358cfc7571c6afa54ad.tar.gz
cmake-317dbdb79761ef65e45c7358cfc7571c6afa54ad.tar.bz2
cmake-317dbdb79761ef65e45c7358cfc7571c6afa54ad.zip
Imported Upstream version 2.8.12.2upstream/2.8.12.2sandbox/kevinthierry/upstream
Diffstat (limited to 'Source/cmcldeps.cxx')
-rw-r--r--Source/cmcldeps.cxx35
1 files changed, 25 insertions, 10 deletions
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 04dab59d0..85715574f 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -62,8 +62,8 @@ static std::string trimLeadingSpace(const std::string& cmdline) {
return cmdline.substr(i);
}
-static void doEscape(std::string& str, const std::string& search,
- const std::string& repl) {
+static void replaceAll(std::string& str, const std::string& search,
+ const std::string& repl) {
std::string::size_type pos = 0;
while ((pos = str.find(search, pos)) != std::string::npos) {
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"
// are removed from the argument if there were any.
static std::string getArg(std::string& cmdline) {
@@ -117,6 +121,13 @@ static void parseCommandLine(LPTSTR wincmdline,
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,
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?
if (!out)
return;
+ std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
+ replaceAll(cwd, "/", "\\");
+ cwd += "\\";
std::string tmp = objfile;
- doEscape(tmp, " ", "\\ ");
+ escapePath(tmp);
fprintf(out, "%s: \\\n", tmp.c_str());
std::vector<std::string>::iterator it = incs.begin();
for (; it != incs.end(); ++it) {
tmp = *it;
- doEscape(tmp, "\\", "/");
- doEscape(tmp, " ", "\\ ");
+ // The paths need to match the ones used to identify build artifacts in the
+ // 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());
}
@@ -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) {
return str.find(what) != std::string::npos;
}
@@ -225,7 +240,7 @@ static int process( const std::string& srcfilename,
int main() {
- // Use the Win32 api instead of argc/argv so we can avoid interpreting the
+ // Use the Win32 API instead of argc/argv so we can avoid interpreting the
// rest of command line after the .d and .obj. Custom parsing seemed
// preferable to the ugliness you get into in trying to re-escape quotes for
// subprocesses, so by avoiding argc/argv, the subprocess is called with