CMake:通过 NVCC 传递编译器标志列表

Edd*_*lis 6 cuda cmake nvcc

我正在尝试编译一些 CUDA,并且希望显示编译器警告。相当于:

g++ fish.cpp -Wall -Wextra
Run Code Online (Sandbox Code Playgroud)

除了 NVCC 不理解这些,你必须通过它们:

nvcc fish.cu --compiler-options -Wall --compiler-options -Wextra
nvcc fish.cu --compiler-options "-Wall -Wextra"
Run Code Online (Sandbox Code Playgroud)

(我喜欢后一种形式,但最终,这并不重要。)

鉴于此 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)
Run Code Online (Sandbox Code Playgroud)

但这扩展到:

nvcc "--compiler-options  -Wall" -Wextra   ...
Run Code Online (Sandbox Code Playgroud)

这显然是错误的。(省略生成器表达式周围的引号只会让我们陷入破碎的扩展地狱。)

...跳过蒙特卡洛编程的数千次迭代...

我已经到达了这个宝石:

set( temp ${cxx_warning_flags} )
string (REPLACE ";" " " temp "${temp}")
set( temp2 "--compiler-options \"${temp}\"" )
message( "${temp2}" )
Run Code Online (Sandbox Code Playgroud)

打印出看起来令人鼓舞的

--compiler-options "-Wall -Wextra"
Run Code Online (Sandbox Code Playgroud)

但是之后

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp2}>")
Run Code Online (Sandbox Code Playgroud)

扩展到:

nvcc "--compiler-options \"-Wall -Wextra\""   ...
Run Code Online (Sandbox Code Playgroud)

我不知所措;我在这里陷入了死胡同吗?或者我错过了一些重要的标点符号组合?

Edd*_*lis 7

我正在回答我自己的问题,因为我找到了一些有效的解决方案,但我仍然有兴趣听到是否有更好的(阅读:更干净、更规范)的方法。

长话短说

foreach(flag IN LISTS cxx_warning_flags)
    add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
Run Code Online (Sandbox Code Playgroud)

详细账户

我试过这个:

foreach(flag IN LISTS cxx_warning_flags)
    add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${flag}>")
endforeach()
Run Code Online (Sandbox Code Playgroud)

但这仍然给了

nvcc  "--compiler-options -Wall" "--compiler-options -Wextra"   
nvcc fatal   : Unknown option '-compiler-options -Wall'
Run Code Online (Sandbox Code Playgroud)

但是添加临时的:

foreach(flag IN LISTS cxx_warning_flags)
    set( temp --compiler-options ${flag}) # no quotes
    add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp}>")
endforeach()
Run Code Online (Sandbox Code Playgroud)

给出了新的结果:

nvcc  --compiler-options -Wall -Wextra   ...
nvcc fatal   : Unknown option 'Wextra'
Run Code Online (Sandbox Code Playgroud)

假设这里发生的是 CMake 正在组合重复的--compiler-options标志,但我只是猜测。

因此,我尝试使用等号消除空格:

foreach(flag IN LISTS cxx_warning_flags)
    add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
Run Code Online (Sandbox Code Playgroud)

欢呼!我们有一个赢家:

nvcc  --compiler-options=-Wall --compiler-options=-Wextra  ...
Run Code Online (Sandbox Code Playgroud)

尾声

我们可以在没有循环的情况下做到这一点吗?

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${cxx_warning_flags}>")
Run Code Online (Sandbox Code Playgroud)

不起作用 ( --compiler-options=-Wall -Wextra),但是:

string (REPLACE ";" " " temp "${cxx_warning_flags}")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${temp}>")
Run Code Online (Sandbox Code Playgroud)

有效"--compiler-options=-Wall -Wextra")。

我对最后一个选择有点惊讶,但我想这是有道理的。总的来说,我认为循环选项的意图是最清楚的。


编辑:在使用 CMake 通过 NVCC 传递给 MSVC 的混淆标志中,我花了很多时间发现使用它可能更好:

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${flag}>")
Run Code Online (Sandbox Code Playgroud)

因为 CMake似乎对标志进行了一些合理化以删除重复项和歧义,但没有意识到这--compiler-options与它所青睐的-Xcompiler.