Ninja: Use absolute path to COMSPEC if possible

If the COMSPEC is set to an absolute path, use it instead of just
`cmd.exe`.  This avoids searching for the tool in the current working
directory and the `PATH`.  If COMSPEC is not set to an absolute path,
fall back to the existing behavior.

Issue: #18350
This commit is contained in:
scivision
2023-08-21 00:40:34 -04:00
committed by Brad King
parent 1345928f96
commit 6ebf0e1a46
3 changed files with 20 additions and 1 deletions

View File

@@ -554,6 +554,15 @@ cmGlobalNinjaGenerator::cmGlobalNinjaGenerator(cmake* cm)
{
#ifdef _WIN32
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";
}
#endif
this->FindMakeProgramFile = "CMakeNinjaFindMake.cmake";
}

View File

@@ -282,6 +282,10 @@ public:
};
MapToNinjaPathImpl MapToNinjaPath() { return { this }; }
#ifdef _WIN32
std::string const& GetComspec() const { return this->Comspec; }
#endif
// -- Additional clean files
void AddAdditionalCleanFile(std::string fileName, const std::string& config);
const char* GetAdditionalCleanTargetName() const
@@ -592,6 +596,11 @@ private:
codecvt_Encoding NinjaExpectedEncoding = codecvt_Encoding::None;
#ifdef _WIN32
// Windows Command shell.
std::string Comspec;
#endif
bool DiagnosedCxxModuleNinjaSupport = false;
void InitOutputPathPrefix();

View File

@@ -538,13 +538,14 @@ std::string cmLocalNinjaGenerator::BuildCommandLine(
std::ostringstream cmd;
#ifdef _WIN32
cmGlobalNinjaGenerator const* gg = this->GetGlobalNinjaGenerator();
bool const needCMD =
cmdLines.size() > 1 || (customStep.empty() && RuleNeedsCMD(cmdLines[0]));
for (auto li = cmdLines.begin(); li != cmdLines.end(); ++li) {
if (li != cmdLines.begin()) {
cmd << " && ";
} else if (needCMD) {
cmd << "cmd.exe /C \"";
cmd << gg->GetComspec() << " /C \"";
}
// Put current cmdLine in brackets if it contains "||" because it has
// higher precedence than "&&" in cmd.exe