summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2024-08-22 13:02:53 (GMT)
committerKitware Robot <kwrobot@kitware.com>2024-08-22 13:03:05 (GMT)
commit3d61720112c827fc8cfa3d72ed1e76c7ed203186 (patch)
tree971a12cb325614f4820d400038d056fbf5af4c4e
parent497b43b997c653855c1c37eb8bce16ac49982527 (diff)
parent8d1803d463adac8ebc63bb0d1a9ef55b6c56472a (diff)
downloadCMake-3d61720112c827fc8cfa3d72ed1e76c7ed203186.zip
CMake-3d61720112c827fc8cfa3d72ed1e76c7ed203186.tar.gz
CMake-3d61720112c827fc8cfa3d72ed1e76c7ed203186.tar.bz2
Merge topic 'autogen-predefs-emscripten'
8d1803d463 AutoGen: Run batch scripts using cmd.exe on windows platforms explicitly 9ab270f47d cmSystemTools: Add GetComspec method to get cmd on Windows Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !9733
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx8
-rw-r--r--Source/cmQtAutoMocUic.cxx56
-rw-r--r--Source/cmSystemTools.cxx11
-rw-r--r--Source/cmSystemTools.h3
4 files changed, 71 insertions, 7 deletions
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 7d62fa8..b051d67 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -573,13 +573,7 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
cm->GetState()->SetWindowsShell(true);
// Attempt to use full path to COMSPEC, default "cmd.exe"
- std::string comspec;
- if (cmSystemTools::GetEnv("COMSPEC", comspec) &&
- cmSystemTools::FileIsFullPath(comspec)) {
- this->Comspec = comspec;
- } else {
- this->Comspec = "cmd.exe";
- }
+ this->Comspec = cmSystemTools::GetComspec();
#endif
cm->GetState()->SetNinja(true);
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
diff --git a/Source/cmQtAutoMocUic.cxx b/Source/cmQtAutoMocUic.cxx
index 408a22c..c07f361 100644
--- a/Source/cmQtAutoMocUic.cxx
+++ b/Source/cmQtAutoMocUic.cxx
@@ -345,6 +345,8 @@ 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,
@@ -848,6 +850,54 @@ 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()) {
+ const auto& 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,
@@ -891,6 +941,9 @@ void cmQtAutoMocUicT::JobMocPredefsT::Process()
cm::append(cmd, this->MocConst().OptionsIncludes);
// Check if response file is necessary
MaybeWriteResponseFile(this->MocConst().PredefsFileAbs, cmd);
+
+ MaybePrependCmdExe(cmd);
+
// Execute command
if (!this->RunProcess(GenT::MOC, result, cmd, reason.get())) {
this->LogCommandError(GenT::MOC,
@@ -2090,6 +2143,7 @@ void cmQtAutoMocUicT::JobCompileMocT::Process()
cmd.push_back(sourceFile);
MaybeWriteResponseFile(outputFile, cmd);
+ MaybePrependCmdExe(cmd);
}
// Execute moc command
@@ -2156,6 +2210,8 @@ void cmQtAutoMocUicT::JobCompileUicT::Process()
cmd.emplace_back(outputFile);
cmd.emplace_back(sourceFile);
+ MaybePrependCmdExe(cmd);
+
cmWorkerPool::ProcessResultT result;
if (this->RunProcess(GenT::UIC, result, cmd, this->Reason.get())) {
// Uic command success
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 136dc93..0a6b683 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -970,6 +970,17 @@ cmSystemTools::WindowsVersion cmSystemTools::GetWindowsVersion()
result.dwBuildNumber = osviex.dwBuildNumber;
return result;
}
+
+std::string cmSystemTools::GetComspec()
+{
+ std::string comspec;
+ if (!cmSystemTools::GetEnv("COMSPEC", comspec) ||
+ !cmSystemTools::FileIsFullPath(comspec)) {
+ comspec = "cmd.exe";
+ }
+ return comspec;
+}
+
#endif
std::string cmSystemTools::GetRealPathResolvingWindowsSubst(
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index a07c749..d0b6046 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -585,6 +585,9 @@ public:
unsigned int dwBuildNumber;
};
static WindowsVersion GetWindowsVersion();
+
+ /** Attempt to get full path to COMSPEC, default "cmd.exe" */
+ static std::string GetComspec();
#endif
/** Get the real path for a given path, removing all symlinks.