diff options
author | Brad King <brad.king@kitware.com> | 2020-04-10 19:15:21 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-04-15 12:34:49 (GMT) |
commit | d74e651b7834937a6761b880d4e713683f5a44e3 (patch) | |
tree | afb3c0b0976c36b78ae756d5a9f4ffa3b11ec416 /Source/cmGlobalUnixMakefileGenerator3.cxx | |
parent | 031bfaa865956c101aff74d35573381ebe71f0a1 (diff) | |
download | CMake-d74e651b7834937a6761b880d4e713683f5a44e3.zip CMake-d74e651b7834937a6761b880d4e713683f5a44e3.tar.gz CMake-d74e651b7834937a6761b880d4e713683f5a44e3.tar.bz2 |
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.cxx | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx index 8a41d49..5363ea5 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( |