diff options
author | Brad King <brad.king@kitware.com> | 2024-08-22 13:02:53 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2024-08-22 13:03:05 (GMT) |
commit | 3d61720112c827fc8cfa3d72ed1e76c7ed203186 (patch) | |
tree | 971a12cb325614f4820d400038d056fbf5af4c4e | |
parent | 497b43b997c653855c1c37eb8bce16ac49982527 (diff) | |
parent | 8d1803d463adac8ebc63bb0d1a9ef55b6c56472a (diff) | |
download | CMake-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.cxx | 8 | ||||
-rw-r--r-- | Source/cmQtAutoMocUic.cxx | 56 | ||||
-rw-r--r-- | Source/cmSystemTools.cxx | 11 | ||||
-rw-r--r-- | Source/cmSystemTools.h | 3 |
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. |