mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-19 11:18:40 +08:00
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
This commit is contained in:
@@ -486,17 +486,25 @@ void cmGlobalUnixMakefileGenerator3::WriteDirectoryRules2(
|
||||
}
|
||||
}
|
||||
|
||||
std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
|
||||
std::string const& path) const
|
||||
namespace {
|
||||
std::string ConvertToMakefilePathForUnix(std::string const& path)
|
||||
{
|
||||
std::string const& out = cmSystemTools::ConvertToOutputPath(path);
|
||||
std::string result;
|
||||
result.reserve(out.size());
|
||||
for (char c : out) {
|
||||
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;
|
||||
@@ -505,6 +513,51 @@ std::string cmGlobalUnixMakefileGenerator3::ConvertToMakefilePath(
|
||||
return result;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
std::string ConvertToMakefilePathForWindows(std::string const& path)
|
||||
{
|
||||
bool const quote = path.find_first_of(" #") != std::string::npos;
|
||||
std::string result;
|
||||
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(
|
||||
const std::string& makeProgram, const std::string& /*projectName*/,
|
||||
|
Reference in New Issue
Block a user