Search code examples
cmake

CMAKE_CXX_FLAGS treats every space as a delimiter for compiler flags and spaces are required within a single option


I am using cmake on a project and changing the value of CMAKE_CXX_FLAGS in a toolchain file, but the change is not doing what I intend. Here is the cmake toolchain file I am using to specify the compiler, add compiler flags, and add linker flags.

set(CMAKE_SYSTEM_NAME Windows)
set(CMAKE_SYSTEM_PROCESSOR AMD64)

set(compiler "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe")
set(CMAKE_C_COMPILER ${compiler})
set(CMAKE_CXX_COMPILER ${compiler})

set(prgx86 "C:/Program Files (x86)")
set(winkit_include_root "${prgx86}/Windows Kits/10/Include/10.0.18326.0")

set(inc_a "/I/\"${prgx86}/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/include\"")
set(inc_b "/I/\"${winkit_include_root}/um\"")
set(inc_c "/I/\"${winkit_include_root}/ucrt\"")
set(inc_d "/I/\"${winkit_include_root}/shared\"")
set(CMAKE_C_FLAGS "${inc_a} ${inc_b} ${inc_c} ${inc_d}")
set(CMAKE_CXX_FLAGS "${inc_a} ${inc_b} ${inc_c} ${inc_d}")


set(lib_a "/LIBPATH:\"${prgx86}/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/lib/x64\"")
set(lib_b "/LIBPATH:\"${prgx86}/Windows Kits/10/Lib/10.0.18326/um/x64\"")
set(lib_c "/LIBPATH:\"${prgx86}/Windows Kits/10/Lib/10.0.18326/ucrt/x64\"")
set(CMAKE_EXE_LINKER_FLAGS "${lib_a} ${lib_b} ${lib_c}")

The problem here is the set(CMAKE_CXX_FLAGS "...") line. When I attempt to use this toolchain file, cmake fails to build the simple test program. This is the monstrosity I found in CMakeError.log after running cmake.

Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" failed.
Compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.27.29110/bin/Hostx64/x64/cl.exe 
Build flags: /I/"C:/Program;Files;(x86)/Microsoft;Visual;Studio/2019/Community/VC/Tools/MSVC/14.27.29110/include";/I/"C:/Program;Files;(x86)/Windows;Kits/10/Include/10.0.18326.0/um";/I/"C:/Program;Files;(x86)/Windows;Kits/10/Include/10.0.18326.0/ucrt";/I/"C:/Program;Files;(x86)/Windows;Kits/10/Include/10.0.18326.0/shared"
Id flags:  

The output was:
2
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29111 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

cl : Command line warning D9024 : unrecognized source file type 'Files', object file assumed
cl : Command line warning D9024 : unrecognized source file type '(x86)/Microsoft', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Visual', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Studio/2019/Community/VC/Tools/MSVC/14.27.29110/include"', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Files', object file assumed
cl : Command line warning D9024 : unrecognized source file type '(x86)/Windows', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Kits/10/Include/10.0.18326.0/um"', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Files', object file assumed
cl : Command line warning D9024 : unrecognized source file type '(x86)/Windows', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Kits/10/Include/10.0.18326.0/ucrt"', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Files', object file assumed
cl : Command line warning D9024 : unrecognized source file type '(x86)/Windows', object file assumed
cl : Command line warning D9024 : unrecognized source file type 'Kits/10/Include/10.0.18326.0/shared"', object file assumed
CMakeCXXCompilerId.cpp
Microsoft (R) Incremental Linker Version 14.27.29111.0
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:Files.exe 
Files 
(x86)/Microsoft 
Visual 
Studio/2019/Community/VC/Tools/MSVC/14.27.29110/include\ 
Files 
(x86)/Windows 
Kits/10/Include/10.0.18326.0/um\ 
Files 
(x86)/Windows 
Kits/10/Include/10.0.18326.0/ucrt\ 
Files 
(x86)/Windows 
Kits/10/Include/10.0.18326.0/shared\ 
CMakeCXXCompilerId.obj 
LINK : fatal error LNK1181: cannot open input file 'Files.obj'


Detecting C compiler ABI info failed to compile with the following output:
Change Dir: C:/Users/underdisc/home/tech/varkor/build/msvc64/CMakeFiles/CMakeTmp

It seems pretty obvious that cmake is interpreting every space as a delimiter for different flags when they are actually a part of a single flag. I have tried escaping these spaces with backslashes and the results are the same. Is there a way to pass these flags to the compiler as intended? The version of cmake is 3.18.1.

Small Note

This is unrelated to the question, but very related to what I am doing in case anyone is curious about what they are looking at. I am trying to build my project from within my mintty-tmux terminal setup on windows. I want to avoid using the developer command prompt that ships with visual studio. I have tried using the vcvars[32|64].bat files in the past and again recently, but they have never worked. I think this has to do with the cygwin setup I have, but I have never known exactly why. I only use a limited set of things from cygwin too. For example, I am using a native windows build of cmake, not the one shipped with cygwin.


Solution

  • This was a bug with cmake that has since been fixed. It is now possible to escape spaces using \ as normal. It was fixed in this pr. https://gitlab.kitware.com/cmake/cmake/-/merge_requests/8158