CUDA: Escape comma in compile definitions for NVCC
The problem that I have is best explained when invoking GCC and NVCC without CMake first to explain their behavior
➜ cat main.cpp
auto main() -> int
{
int array[] = { FOO };
return 0;
}
➜ g++ '-DFOO=2, 2' main.cpp -E
# 0 "main.cpp"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "main.cpp"
auto main() -> int
{
int array[] = { 2, 2 };
return 0;
}
➜ nvcc '-DFOO=2, 2' main.cpp
<command-line>: error: macro names must be identifiers
➜ nvcc '-DFOO=2, 2' main.cpp -E
# 0 "main.cpp"
# 0 "<built-in>"
# 0 "<command-line>"
<command-line>: error: macro names must be identifiers
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "main.cpp"
auto main() -> int
{
int array[] = { 2 };
return 0;
}
➜ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Thu_Nov_18_09:45:30_PST_2021
Cuda compilation tools, release 11.5, V11.5.119
Build cuda_11.5.r11.5/compiler.30672275_0
➜ g++ --version
g++ (Ubuntu 11.2.0-7ubuntu2) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The reason for this behavior is that nvcc parses the argument of -D
as a comma-separated key-value list. To get normal parsing, the comma can be escaped.
➜ nvcc '-DFOO=2\, 2' main.cpp -E
# 0 "main.cpp"
# 0 "<built-in>"
# 0 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 0 "<command-line>" 2
# 1 "main.cpp"
auto main() -> int
{
int array[] = { 2, 2 };
return 0;
}
This does, however, not work with gcc
➜ clang-14 '-DFOO=2\, 2' main.cpp -E
# 1 "main.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 386 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "main.cpp" 2
auto main() -> int
{
int array[] = { 2\, 2 };
return 0;
}
clang has the same behavior as gcc.
When you now define a simple CMakeLists.txt that uses target_compile_definitions
and CUDA and C++ files, the following won't work
project(nvcc-compile-definition-parsing-bug CXX CUDA)
cmake_minimum_required(VERSION 3.22)
set(CMAKE_CUDA_ARCHITECTURES 50)
add_executable(nvcc-compile-definition-parsing-bug
cuda_file.cu
cpp_file.cpp
)
set_target_properties(nvcc-compile-definition-parsing-bug PROPERTIES
CXX_STANDARD 17
CXX_EXTENSIONS OFF
)
target_compile_definitions(nvcc-compile-definition-parsing-bug PRIVATE
"-DFOO=2, 2" # nvcc would require "-DFOO=2\\, 2" while gcc wants "-DFOO=2, 2"
)
Would it be possible to introduce a cmake policy to auto-escape ,
for nvcc compile definitions to have consistent behavior between the different compilers involved in a target?
This issue seems to be related: #16510 (closed)
Edited by Brad King