cmSystemTools: Adopt MaybePrependCmdExe

This commit is contained in:
Brad King 2025-01-31 10:50:09 -05:00
parent f28d76aeb4
commit 98fed0f116
3 changed files with 52 additions and 53 deletions

View File

@ -344,8 +344,6 @@ public:
void MaybeWriteResponseFile(std::string const& outputFile,
std::vector<std::string>& cmd) const;
static void MaybePrependCmdExe(std::vector<std::string>& cmd);
/** @brief Run an external process. Use only during Process() call! */
bool RunProcess(GenT genType, cmWorkerPool::ProcessResultT& result,
std::vector<std::string> const& command,
@ -846,54 +844,6 @@ void cmQtAutoMocUicT::JobT::MaybeWriteResponseFile(
#endif
}
/*
* According to the CreateProcessW documentation which is the underlying
* function for all RunProcess calls:
*
* "To run a batch file, you must start the command interpreter; set"
* "lpApplicationName to cmd.exe and set lpCommandLine to the following"
* "arguments: /c plus the name of the batch file."
*
* we should to take care of the correctness of the command line when
* attempting to execute the batch files.
*
* Also cmd.exe is unable to parse batch file names correctly if they
* contain spaces. This function uses cmSystemTools::GetShortPath conversion
* to suppress this behavior.
*
* The function is noop on platforms different from the pure WIN32 one.
*/
void cmQtAutoMocUicT::JobT::MaybePrependCmdExe(
std::vector<std::string>& cmdLine)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!cmdLine.empty()) {
auto const& applicationName = cmdLine.at(0);
if (cmSystemTools::StringEndsWith(applicationName, ".bat") ||
cmSystemTools::StringEndsWith(applicationName, ".cmd")) {
std::vector<std::string> output;
output.reserve(cmdLine.size() + 2);
output.emplace_back(cmSystemTools::GetComspec());
output.emplace_back("/c");
std::string tmpShortPath;
if (applicationName.find(' ') != std::string::npos &&
cmSystemTools::GetShortPath(applicationName, tmpShortPath)) {
// If the batch file name contains spaces convert it to the windows
// short path. Otherwise it might cause issue when running cmd.exe.
output.emplace_back(tmpShortPath);
} else {
output.push_back(applicationName);
}
std::move(cmdLine.begin() + 1, cmdLine.end(),
std::back_inserter(output));
cmdLine = std::move(output);
}
}
#else
static_cast<void>(cmdLine);
#endif
}
bool cmQtAutoMocUicT::JobT::RunProcess(GenT genType,
cmWorkerPool::ProcessResultT& result,
std::vector<std::string> const& command,
@ -938,7 +888,7 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process()
// Check if response file is necessary
MaybeWriteResponseFile(this->MocConst().PredefsFileAbs, cmd);
MaybePrependCmdExe(cmd);
cmSystemTools::MaybePrependCmdExe(cmd);
// Execute command
if (!this->RunProcess(GenT::MOC, result, cmd, reason.get())) {
@ -2141,7 +2091,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
cmd.push_back(sourceFile);
MaybeWriteResponseFile(outputFile, cmd);
MaybePrependCmdExe(cmd);
cmSystemTools::MaybePrependCmdExe(cmd);
}
// Execute moc command
@ -2208,7 +2158,7 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
cmd.emplace_back(outputFile);
cmd.emplace_back(sourceFile);
MaybePrependCmdExe(cmd);
cmSystemTools::MaybePrependCmdExe(cmd);
cmWorkerPool::ProcessResultT result;
if (this->RunProcess(GenT::UIC, result, cmd, this->Reason.get())) {

View File

@ -787,6 +787,36 @@ std::size_t cmSystemTools::CalculateCommandLineLengthLimit()
return sz;
}
void cmSystemTools::MaybePrependCmdExe(std::vector<std::string>& cmdLine)
{
#if defined(_WIN32) && !defined(__CYGWIN__)
if (!cmdLine.empty()) {
auto const& applicationName = cmdLine.at(0);
if (cmSystemTools::StringEndsWith(applicationName, ".bat") ||
cmSystemTools::StringEndsWith(applicationName, ".cmd")) {
std::vector<std::string> output;
output.reserve(cmdLine.size() + 2);
output.emplace_back(cmSystemTools::GetComspec());
output.emplace_back("/c");
std::string tmpShortPath;
if (applicationName.find(' ') != std::string::npos &&
cmSystemTools::GetShortPath(applicationName, tmpShortPath)) {
// If the batch file name contains spaces convert it to the windows
// short path. Otherwise it might cause issue when running cmd.exe.
output.emplace_back(tmpShortPath);
} else {
output.push_back(applicationName);
}
std::move(cmdLine.begin() + 1, cmdLine.end(),
std::back_inserter(output));
cmdLine = std::move(output);
}
}
#else
static_cast<void>(cmdLine);
#endif
}
bool cmSystemTools::RunSingleCommand(std::vector<std::string> const& command,
std::string* captureStdOut,
std::string* captureStdErr, int* retVal,

View File

@ -234,6 +234,25 @@ public:
static cmsys::Status MoveFileIfDifferent(std::string const& source,
std::string const& destination);
/**
* According to the CreateProcessW documentation which is the underlying
* function for all RunProcess calls:
*
* "To run a batch file, you must start the command interpreter; set"
* "lpApplicationName to cmd.exe and set lpCommandLine to the following"
* "arguments: /c plus the name of the batch file."
*
* we should to take care of the correctness of the command line when
* attempting to execute the batch files.
*
* Also cmd.exe is unable to parse batch file names correctly if they
* contain spaces. This function uses cmSystemTools::GetShortPath conversion
* to suppress this behavior.
*
* The function is noop on platforms different from the pure WIN32 one.
*/
static void MaybePrependCmdExe(std::vector<std::string>& cmdLine);
/**
* Run a single executable command
*