summaryrefslogtreecommitdiff
path: root/Source/cmGlobalUnixMakefileGenerator3.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-04-10 15:15:21 -0400
committerBrad King <brad.king@kitware.com>2020-04-15 08:34:49 -0400
commitd74e651b7834937a6761b880d4e713683f5a44e3 (patch)
treeafb3c0b0976c36b78ae756d5a9f4ffa3b11ec416 /Source/cmGlobalUnixMakefileGenerator3.cxx
parent031bfaa865956c101aff74d35573381ebe71f0a1 (diff)
downloadcmake-d74e651b7834937a6761b880d4e713683f5a44e3.tar.gz
Makefiles: Re-implement makefile target path escaping and quoting
Previously we used `cmSystemTools::ConvertToOutputPath` which internally used KWSys methods * SystemTools::ConvertToUnixOutputPath * SystemTools::ConvertToWindowsOutputPath These were written in very early days of CMake and have some limitations: * They do not encode all characters. E.g. '#' is left out. * They attempt to do some path cleanup and handle existing quotes. These days CMake has clean unquoted paths already. * They attempted to encode paths both for makefile targets and for shell command lines. The latter use has mostly been replaced. * Choosing between the two methods depends on a global variable! Several code paths in CMake have to copy the global generator's member ForceUnixPaths variable over to the cmSystemTools global. Re-implement the `ConvertToMakefilePath` method to drop use of those methods. Compute suitable makefile target path escaping and quoting via local logic. Add support for more characters like '#'. Fixes: #20555
Diffstat (limited to 'Source/cmGlobalUnixMakefileGenerator3.cxx')
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx63
1 files changed, 58 insertions, 5 deletions
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index 8a41d490da..5363ea562a 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -486,24 +486,77 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
}
}
-std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
- std::string const& path) const
+namespace {
+std::string ConvertToMakefilePathForUnix(std::string const& path)
+{
+ std::string result;
+ result.reserve(path.size());
+ for (char c : path) {
+ switch (c) {
+ case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
+ result.append("$(EQUALS)");
+ break;
+ case '$':
+ result.append("$$");
+ break;
+ case '\\':
+ case ' ':
+ case '#':
+ result.push_back('\\');
+ CM_FALLTHROUGH;
+ default:
+ result.push_back(c);
+ break;
+ }
+ }
+ return result;
+}
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+std::string ConvertToMakefilePathForWindows(std::string const& path)
{
- std::string const& out = cmSystemTools::ConvertToOutputPath(path);
+ bool const quote = path.find_first_of(" #") != std::string::npos;
std::string result;
- result.reserve(out.size());
- for (char c : out) {
+ result.reserve(path.size() + (quote ? 2 : 0));
+ if (quote) {
+ result.push_back('"');
+ }
+ for (char c : path) {
switch (c) {
case '=':
+ // We provide 'EQUALS = =' to encode '=' in a non-assignment case.
result.append("$(EQUALS)");
break;
+ case '$':
+ result.append("$$");
+ break;
+ case '/':
+ result.push_back('\\');
+ break;
default:
result.push_back(c);
break;
}
}
+ if (quote) {
+ result.push_back('"');
+ }
return result;
}
+#endif
+}
+
+std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
+ std::string const& path) const
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+ if (!this->ForceUnixPaths) {
+ return ConvertToMakefilePathForWindows(path);
+ }
+#endif
+ return ConvertToMakefilePathForUnix(path);
+}
std::vector<cmGlobalGenerator::GeneratedMakeCommand>
cmGlobalUnixMakefileGenerator3::GenerateBuildCommand(