如何在 CMake 中从 COMPILE_FLAGS 迁移到 target_compile_options?

How do I migrate from COMPILE_FLAGS to target_compile_options in CMake?

我的 CMakeLists.txt 中有以下代码,用于为我的 emscripten 项目设置一些编译器和链接器标志:

旧的工作代码

set_target_properties(prolog_bfs PROPERTIES COMPILE_FLAGS "-s USE_BOOST_HEADERS=1 -s DISABLE_EXCEPTION_CATCHING=0")
set_target_properties(prolog_bfs PROPERTIES LINK_FLAGS "--bind --emrun -s USE_BOOST_HEADERS=1 -s DISABLE_EXCEPTION_CATCHING=0")

这工作得很好,我的编译器被调用了它应该的选项(我仍然想知道 em++ 之后的空格是从哪里来的,但这不是问题):

em++    -s USE_BOOST_HEADERS=1 -s DISABLE_EXCEPTION_CATCHING=0 -std=gnu++17 -o xy.o -c xy.cpp

但是,COMPILE_FLAGSLINK_FLAGSdeprecated,所以我 想迁移到 new/recommended 方法 使用target_compile_options()target_link_options() 代替。

因此,我将 CMakeLists.txt 更改为:

新方法

target_compile_options(prolog_bfs PUBLIC -s USE_BOOST_HEADERS=1;-s DISABLE_EXCEPTION_CATCHING=0)
target_link_options(prolog_bfs PUBLIC --bind;--emrun;-s USE_BOOST_HEADERS=1;-s DISABLE_EXCEPTION_CATCHING=0)

我知道 target_*_options 函数需要用分号分隔标志,我做到了。除此之外,我没有看到任何其他主要差异。

问题

使用这些更改构建我的项目将使编译器像这样调用:

em++    -s USE_BOOST_HEADERS=1 DISABLE_EXCEPTION_CATCHING=0 -std=gnu++17 -o xy.o -c xy.cpp

请注意,第二个标志之前的 -s 丢失了。我不明白为什么它会消失。有趣的是,第一个留在那里。

问题

如何在不丢失 -s 的情况下将我最初的 CMakeLists.txt 代码转换为现代方法?

默认情况下,CMake 去重编译和link选项。 documentation for target_compile_options 命令中明确说明了这一点。此外,文档建议使用 SHELL: 前缀以避免因此而破坏组:

The final set of compile or link options used for a target is constructed by accumulating options from the current target and the usage requirements of its dependencies. The set of options is de-duplicated to avoid repetition. While beneficial for individual options, the de-duplication step can break up option groups. For example, -D A -D B becomes -D A B. One may specify a group of options using shell-like quoting along with a SHELL: prefix. The SHELL: prefix is dropped, and the rest of the option string is parsed using the separate_arguments() UNIX_COMMAND mode. For example, "SHELL:-D A" "SHELL:-D B" becomes -D A -D B.

也就是说,在您的情况下,您可以指定

target_compile_options(prolog_bfs PUBLIC "SHELL:-s USE_BOOST_HEADERS=1" "SHELL:-s DISABLE_EXCEPTION_CATCHING=0")