CUDA/VS: Toolchain file option splitting breaks CUDA builds with Visual Studio generator
When using a toolchain file specifying multiple compiler options, CMake will concatenate them using a semicolon. This semicolon will then be placed in quotation marks when being passed to the compiler leading to several issues. In some cases compiler detection for nvcc fails, in others mangled compiler options get passed to CL.
I was able to confirm this issue using the following configurations.
Generator | CUDA Version | CMake Versions |
---|---|---|
Visual Studio 16 2019 | 11.2 | 3.22.2, 3.23rc-1 |
Visual Studio 17 2022 | 11.6 | 3.22.2, 3.23rc-1 |
With Ninja as generator I did not notice any issue.
Here is a small CMakeLists.txt to reproduce the problem:
cmake_minimum_required(VERSION 3.22)
# set(CMAKE_CUDA_FLAGS_DEBUG_INIT -Xcompiler="/W3 /permissive-" --generate-line-info) # This works partially
set(CMAKE_CUDA_FLAGS_DEBUG_INIT -Xcompiler="/W3" --generate-line-info) # This fails
# set(CMAKE_CUDA_FLAGS_DEBUG_INIT --generate-line-info -Xcompiler="/W3") # This fails
project(Test LANGUAGES CUDA)
set(src "${CMAKE_CURRENT_BINARY_DIR}/main.cu")
file(CONFIGURE OUTPUT ${src} CONTENT "int main(){}")
add_executable(test ${src})
The uncommented examples produces this value for CMAKE_CUDA_FLAGS_DEBUG: -Xcompiler="/W3";--generate-line-info -Xcompiler="-Zi -Ob0 -Od /RTC1"
Leading to this compiler invocation "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\bin\nvcc.exe" -gencode=arch=compute_52,code=\"sm_52,compute_52\" --use-local-env -ccbin "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\bin\HostX64\x64" -x cu -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" --keep-dir x64\Debug -maxrregcount=0 --machine 64 --compile -cudart static -Xcompiler="/EHsc /W3\"";"\"--generate-line-info -Zi -Ob0" -g -D_WINDOWS -D"CMAKE_INTDIR=\"Debug\"" -D_MBCS -D"CMAKE_INTDIR=\"Debug\"" -Xcompiler "/EHsc /W1 /nologo /Od /FdcmTC_21485.dir\Debug\vc143.pdb /FS /Zi /RTC1 /MDd " -o cmTC_21485.dir\Debug\main.obj "D:\build\bad_toolset\CMakeFiles\CMakeTmp\main.cu"
, which fails.