CMake:通过 NVCC 传递编译器标志列表
CMake: pass list of compiler flags through NVCC
我正在尝试编译一些 CUDA,我希望显示编译器警告。相当于:
g++ fish.cpp -Wall -Wextra
除非NVCC不理解这些,你必须通过它们:
nvcc fish.cu --compiler-options -Wall --compiler-options -Wextra
nvcc fish.cu --compiler-options "-Wall -Wextra"
(我更喜欢后一种形式,但最终,这并不重要。)
鉴于此 CMakeLists.txt(一个非常精简的示例):
cmake_minimum_required(VERSION 3.9)
project(test_project LANGUAGES CUDA CXX)
list(APPEND cxx_warning_flags "-Wall" "-Wextra") # ... maybe others
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${cxx_warning_flags}>")
add_executable(test_cuda fish.cu)
但这扩展为:
nvcc "--compiler-options -Wall" -Wextra ...
这显然是错误的。 (省略生成器表达式周围的引号只会让我们陷入崩溃的扩展地狱。)
...向前跳过数千次Monte Carlo 编程迭代...
我已经到了这个 gem:
set( temp ${cxx_warning_flags} )
string (REPLACE ";" " " temp "${temp}")
set( temp2 "--compiler-options \"${temp}\"" )
message( "${temp2}" )
打印出令人鼓舞的样子
--compiler-options "-Wall -Wextra"
但是
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp2}>")
扩展为:
nvcc "--compiler-options \"-Wall -Wextra\"" ...
我很茫然;我在这里走上了死胡同吗?还是我错过了一些关键的标点符号组合?
我正在回答我自己的问题,因为我已经找到了一些可行的解决方案,但我仍然有兴趣听听是否有更好的(阅读:更清晰、更规范的)方法。
TL;DR:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
详解:
我试过这个:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${flag}>")
endforeach()
但这仍然给出
nvcc "--compiler-options -Wall" "--compiler-options -Wextra"
nvcc fatal : Unknown option '-compiler-options -Wall'
但临时添加:
foreach(flag IN LISTS cxx_warning_flags)
set( temp --compiler-options ${flag}) # no quotes
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp}>")
endforeach()
给出新结果:
nvcc --compiler-options -Wall -Wextra ...
nvcc fatal : Unknown option 'Wextra'
我假设 在这里发生的是 CMake 正在组合重复的 --compiler-options
标志,但我只是推测。
因此,我尝试使用等号消除空格:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
万岁!我们有一个赢家:
nvcc --compiler-options=-Wall --compiler-options=-Wextra ...
结语:
我们可以不用循环吗?
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${cxx_warning_flags}>")
不起作用 (--compiler-options=-Wall -Wextra
),但是:
string (REPLACE ";" " " temp "${cxx_warning_flags}")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${temp}>")
有效 ("--compiler-options=-Wall -Wextra"
)。
我对最后一个选项感到有些惊讶,但我想这是有道理的。总的来说,我认为循环选项的意图最明确。
编辑:
在中,我花了很多时间发现使用:
可能会更好
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${flag}>")
因为 CMake 出现 对标志进行一些合理化以消除重复和歧义,但没有意识到 --compiler-options
与其青睐的 -Xcompiler
.
我正在尝试编译一些 CUDA,我希望显示编译器警告。相当于:
g++ fish.cpp -Wall -Wextra
除非NVCC不理解这些,你必须通过它们:
nvcc fish.cu --compiler-options -Wall --compiler-options -Wextra
nvcc fish.cu --compiler-options "-Wall -Wextra"
(我更喜欢后一种形式,但最终,这并不重要。)
鉴于此 CMakeLists.txt(一个非常精简的示例):
cmake_minimum_required(VERSION 3.9)
project(test_project LANGUAGES CUDA CXX)
list(APPEND cxx_warning_flags "-Wall" "-Wextra") # ... maybe others
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${cxx_warning_flags}>")
add_executable(test_cuda fish.cu)
但这扩展为:
nvcc "--compiler-options -Wall" -Wextra ...
这显然是错误的。 (省略生成器表达式周围的引号只会让我们陷入崩溃的扩展地狱。)
...向前跳过数千次Monte Carlo 编程迭代...
我已经到了这个 gem:
set( temp ${cxx_warning_flags} )
string (REPLACE ";" " " temp "${temp}")
set( temp2 "--compiler-options \"${temp}\"" )
message( "${temp2}" )
打印出令人鼓舞的样子
--compiler-options "-Wall -Wextra"
但是
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp2}>")
扩展为:
nvcc "--compiler-options \"-Wall -Wextra\"" ...
我很茫然;我在这里走上了死胡同吗?还是我错过了一些关键的标点符号组合?
我正在回答我自己的问题,因为我已经找到了一些可行的解决方案,但我仍然有兴趣听听是否有更好的(阅读:更清晰、更规范的)方法。
TL;DR:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
详解:
我试过这个:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${flag}>")
endforeach()
但这仍然给出
nvcc "--compiler-options -Wall" "--compiler-options -Wextra"
nvcc fatal : Unknown option '-compiler-options -Wall'
但临时添加:
foreach(flag IN LISTS cxx_warning_flags)
set( temp --compiler-options ${flag}) # no quotes
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp}>")
endforeach()
给出新结果:
nvcc --compiler-options -Wall -Wextra ...
nvcc fatal : Unknown option 'Wextra'
我假设 在这里发生的是 CMake 正在组合重复的 --compiler-options
标志,但我只是推测。
因此,我尝试使用等号消除空格:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
万岁!我们有一个赢家:
nvcc --compiler-options=-Wall --compiler-options=-Wextra ...
结语:
我们可以不用循环吗?
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${cxx_warning_flags}>")
不起作用 (--compiler-options=-Wall -Wextra
),但是:
string (REPLACE ";" " " temp "${cxx_warning_flags}")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${temp}>")
有效 ("--compiler-options=-Wall -Wextra"
)。
我对最后一个选项感到有些惊讶,但我想这是有道理的。总的来说,我认为循环选项的意图最明确。
编辑:
在
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${flag}>")
因为 CMake 出现 对标志进行一些合理化以消除重复和歧义,但没有意识到 --compiler-options
与其青睐的 -Xcompiler
.