CMake fails to compile test program on Windows using generator "MinGW Makefiles" when installed in network location
**Summary** The "Check for working C Compiler" step fails when CMake is installed in a network location and the "MinGW Makefiles" generator is used, with the following syndrome: ``` The C compiler "G:/MinGW/bin/gcc.exe" is not able to compile a simple test program. It fails with the following output: Change Dir: U:/scratch/cmake_mingw_bug/CMakeFiles/CMakeTmp Run Build Command(s):G:/MinGW/bin/mingw32-make.exe cmTC_07339/fast && G:/MinGW/bin/mingw32-make.exe -f CMakeFiles\cmTC_07339.dir\build.make CMakeFiles/cmTC_07339.dir/build mingw32-make.exe[1]: Entering directory 'U:/scratch/cmake_mingw_bug/CMakeFiles/CMakeTmp' process_begin: CreateProcess(NULL, \server\share\bin\cmake.exe -E cmake_echo_color --switch= --progress-dir=U:\scratch\cmake_mingw_bug\CMakeFiles\CMakeTmp\CMakeFiles --progress-num=1 "Building C object CMakeFiles/cmTC_07339.dir/testCCompiler.c.obj", ...) failed. make (e=2): The system cannot find the file specified. mingw32-make.exe[1]: *** [CMakeFiles\cmTC_07339.dir\build.make:83: CMakeFiles/cmTC_07339.dir/testCCompiler.c.obj] Error 2 mingw32-make.exe[1]: Leaving directory 'U:/scratch/cmake_mingw_bug/CMakeFiles/CMakeTmp' mingw32-make.exe: *** [Makefile:139: cmTC_07339/fast] Error 2 ``` **Reproduction Steps** This appears to still be reproducible with an installation built from the ``master`` branch. 1. Install CMake on a mapped network drive on Windows. 2. Try to build a project using that installation of CMake and the ``MinGW Makefiles`` generator. **Analysis** It appears that CMake always resolves a canonical UNC path to the CMake executable, even if it is on a mapped drive, and the root cause appears to be related to the definition of the variable in the generated makefile: ``` CMAKE_COMMAND = \\server\share\bin\cmake.exe ``` It looks like gmake interprets the first backslash in ``\\`` as an escape character. Prepending a further escaped backslash would half solve the problem, except it also looks like there are some situations where the ``$(CMAKE_COMMAND)`` expansion is used as arguments to external tools that do not interpret the backslash as an escape character, for example, when getting CMake to re-build itself in the following excerpt, the additional escape is needed in the first line, but not the second or third. ``` @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --green --bold --progress-dir=T:\cmake_win\winbuild\CMakeFiles --progress-num=$(CMAKE_PROGRESS_18) "Linking CXX static library libcmsys.a" cd /d T:\cmake_win\winbuild\Source\kwsys && $(CMAKE_COMMAND) -P CMakeFiles\cmsys.dir\cmake_clean_target.cmake cd /d T:\cmake_win\winbuild\Source\kwsys && $(CMAKE_COMMAND) -E cmake_link_script CMakeFiles\cmsys.dir\link.txt --verbose=$(VERBOSE) ``` Therefore, a practical option might be to encapsulate UNC paths in quotes when using the "MinGW Makefiles" generator for example, e.g., ``` CMAKE_COMMAND = "\\server\share\bin\cmake.exe" ``` I was able to get CMake hosted on a network drive to rebuild another instance of CMake, by applying the following modification: ``` --- a/Source/cmOutputConverter.cxx +++ b/Source/cmOutputConverter.cxx @@ -527,6 +527,13 @@ bool cmOutputConverter::Shell_ArgumentNeedsQuotes(cm::string_view in, } } + /* UNC paths in MinGW Makefiles need quotes */ + if ((flags & Shell_Flag_MinGWMake) && (flags & Shell_Flag_Make) && in.size() > 1) { + if (in[0] == '\\' && in[1] == '\\') { + return true; + } + } + return false; } ```
issue