in Windows, add path to cmd.exe when generating files
I have encountered an issue running CMake in VS2017 as part of the Linux tools (GDB) support. For some reason it will not find and execute cmd.exe, even if cmd.exe is on the PATH. [Visual Studio Code works as expected, so it is something specific to VS2017].
I have logged an issue here: https://github.com/Microsoft/VSLinux/issues/330
My suggested fix is to let CMake find cmd.exe and add the path to the generated files.
i.e. current behavior will create files along the lines of the following. Note the cmd.exe at the start of COMMAND. This is further complicated when nest calls are made to cmd.exe.
#############################################
# Utility command for edit_cache
build CMakeFiles/edit_cache.util: CUSTOM_COMMAND
COMMAND = cmd.exe /C "cd /D C:\Projects\nf\nf-interpreter\build && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake-gui.exe" -HC:\Projects\nf\nf-interpreter -BC:\Projects\nf\nf-interpreter\build"
DESC = Running CMake cache editor...
pool = console
restat = 1
build edit_cache: phony CMakeFiles/edit_cache.util
#############################################
the changes suggested below will cause the output to be:
#############################################
# Utility command for edit_cache
build CMakeFiles/edit_cache.util: CUSTOM_COMMAND
COMMAND = C:\WINDOWS\system32\cmd.exe /C "cd /D C:\Projects\nf\nf-interpreter\build && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake-gui.exe" -HC:\Projects\nf\nf-interpreter -BC:\Projects\nf\nf-interpreter\build"
DESC = Running CMake cache editor...
pool = console
restat = 1
build edit_cache: phony CMakeFiles/edit_cache.util
#############################################
The files that need to be updated (i.e. search for cmd.exe)
Source\cmGlobalNinjaGenerator.cxx
#ifdef _WIN32
if (cmd.empty())
// TODO Shouldn't an empty command be handled by ninja?
// cmd = "cmd.exe /c";
// TODO: read environment variable 'COMSPEC' and use that if available.
cmd = "C:\\WINDOWS\\system32\\cmd.exe /c";
#endif
Source\cmLocalNinjaGenerator.cxx
if (li != cmdLines.begin()) {
cmd << " && ";
} else if (cmdLines.size() > 1) {
// cmd << "cmd.exe /C \"";
// TODO: read environment variable 'COMSPEC' and use that if available.
cmd = "C:\\WINDOWS\\system32\\cmd.exe /C";
}
Source\cmLocalUnixMakefileGenerator3.cxx
if (this->IsWindowsShell()) {
// makefileStream << "SHELL = cmd.exe\n"
// TODO: read environment variable 'COMSPEC' and use that if available.
makefileStream << "SHELL = C:\\WINDOWS\\system32\\cmd.exe\n"
<< "\n";
} else {
The same change is required in all along the lines of the following code using the first as an illustration.Maybe this should become a shared method in the cmSystemsTools class?
#ifdef _WIN32
if (cmd.empty())
// TODO Shouldn't an empty command be handled by ninja?
// Find path to cmd.exe, by first looking for Environment Variable COMSPEC
std::string cmdPath;
try {
if (!cmSystemTools::GetEnv("COMSPEC", cmdPath)) {
// Not found, so look on the PATH
cmdPath = cmSystemTools::FindProgram("cmd.exe");
}
if (cmdPath.empty()) {
cmdPath = "cmd.exe";
}
} catch (...) {
cmdPath = "cmd.exe";
}
cmd << cmdPath << " /C \"";
}
#endif