为什么 CMake 对 add_compile_options 和 target_compile_options 的参数分割方式不同?

ick*_*fay 5 cmake

我正在尝试在 CMake 项目中启用警告。使用target_compile_options类似于此答案中建议的方法效果很好:

target_compile_options(mytarget PRIVATE $<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -pedantic>)
Run Code Online (Sandbox Code Playgroud)

我有很多目标,我想将这些设置应用于所有目标。所以,我尝试使用add_compile_options

add_compile_options($<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -pedantic>)
Run Code Online (Sandbox Code Playgroud)

但是,当我使用它时,我看到编译器已通过"\$<1:-Wall" -Wextra "-pedantic>",就好像在扩展生成器表达式之前发生了空间分割一样。这会使编译器感到困惑并且构建失败。

我尝试引用以下论点add_compile_commands

add_compile_options("$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -pedantic>")
Run Code Online (Sandbox Code Playgroud)

但是当我这样做时,编译器会传递一个"-Wall -Wextra -pedantic"参数,这也会使编译器感到困惑并导致构建失败。

我可以像这样“分发”生成器表达式:

add_compile_options(
    $<$<CXX_COMPILER_ID:GNU,Clang>:-Wall>
    $<$<CXX_COMPILER_ID:GNU,Clang>:-Wextra>
    $<$<CXX_COMPILER_ID:GNU,Clang>:-pedantic>
)
Run Code Online (Sandbox Code Playgroud)

这工作正常,解决了我眼前的问题......

……但是,问题仍然存在:是什么导致add_compile_options工作方式与target_compile_options这里不同?它们的字符串分割语义不应该是相同的吗?

Max*_*axC 3

也就是说,becauseadd_compile_options用于将编译选项添加到COMPILE_OPTIONS列表(分号分隔的列表),而add_target_options将选项添加到datatype 的INTERFACE_COMPILE_OPTIONSproperty

你们离得太近了!只要用分号替换空格,您的代码就会立即生效:

add_compile_options("$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall;-Wextra;-pedantic>")
Run Code Online (Sandbox Code Playgroud)

是的!我还认为,这种行为是不一致的,add_compile_options应该更类似于target_compile_options. 也许其他人可以进一步阐述它的历史,但是当我发现它在代码中出现的频率比:这意味着 121/40 at d231f429f10e9[^_]COMPILE_OPTIONS[^_]更频繁时,我的好奇心得到了满足![^_]INTERFACE_COMPILE_OPTIONS[^_]据此,我认为它已经存在了更长时间,改变它的实现方式很可能会破坏某些用户现有的构建链,而没有人希望这样。