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

jvlzgdj9  于 12个月前  发布在  其他
关注(0)|答案(2)|浏览(147)

我正在尝试编译一些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   ...


这显然是错误的。(省略生成器表达式周围的引号只会让我们陷入破碎的扩展地狱。)
.跳过几千次蒙特卡罗程序的迭代.
我来到了这个宝石:

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\""   ...


我不知所措了,我是走进了死胡同吗?还是我错过了一些关键的标点组合?

3z6pesqy

3z6pesqy1#

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

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标志,但我只是猜测。
所以,我试着用一个equals来消除空格:

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}>")

  • does* work("--compiler-options=-Wall -Wextra").

我对最后一个选项有点惊讶,但我想它是有道理的。总的来说,我认为循环选项的意图是最清楚的。
编辑:在Confusing flags passed to MSVC through NVCC with CMake中,我花了很多时间发现用途:可能更好

add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${flag}>")


因为CMake * 似乎 * 对标志进行了一些合理化处理,以消除重复和歧义,但没有意识到--compiler-options与其偏好的-Xcompiler相同。

daolsyd0

daolsyd02#

NVCC_PREPEND_FLAGS="<your nvcc flags here>" <CMake invocation>(或直接集成到CMake中)是否有效?
我对我的解决方案是否适用于你的问题有点不自信,它看起来太复杂了,但是AFAICT你面临着同样的问题,g++和nvcc理解不同的标志,并希望直接在nvcc上定位标志。

相关问题