如何将 C++ 标准编译选项放在CMake中target/add_compile_options的选项之前?

svmlkihl  于 2023-05-07  发布在  其他
关注(0)|答案(2)|浏览(137)

在我的CMakeLists.txt中有:

set(CMAKE_CXX_STANDARD 20)
# ...
add_library(mytarget)
# ...
target_compile_options(mytarget PRIVATE
    /Zc:char8_t-  # Disables C++20 conforming char8_t type support.
                  # https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1423r3.html
                  # https://stackoverflow.com/questions/59325910/whats-the-msvc-equivalent-for-fno-char8-t
)

如果我使用Visual或Ninja生成器,它会生成不同的命令行。使用Visual Generator:

cl.exe [...] /std:c++20 [...] /Zc:char8_t-

使用Ninja Generator:

cl.exe [...] /Zc:char8_t- [...] -std:c++20

这里编译标志的顺序很重要,因为/std:c++20会重新激活/Zc:char8_t(注意这里没有“-”)。所以使用Ninja构建失败。
在撰写本文时,我使用的是CMake 3.25.1。
有没有办法告诉CMake把/std:c++20放在任何其他编译标志之前?

wribegjk

wribegjk1#

此问题在CMake 3.26里程碑的此问题单中引用:Place language standard flags just after CMAKE__FLAGS #7931
3.26编译特性手册中关于语言标准标志的部分(新添加的部分)指出:
为了满足由target_compile_features()命令或[CMAKE_<LANG>_STANDARD](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_STANDARD.html) variable, CMake may pass a language standard flag to the compiler, such as-std=c++11]指定的要求。
对于Visual Studio生成器,CMake无法精确控制编译器命令行上语言标准标志的位置。对于Ninja Generators、Makefile Generators和Xcode,CMake将语言标准标志放置在CMAKE_<LANG>_FLAGSCMAKE_<LANG>_FLAGS_<CONFIG>的语言范围标志之后。

  • 在版本3.26中更改:* 语言标准标志位于其他抽象(如target_compile_options()命令)指定的标志之前。在CMake 3.26之前,语言标准标志放在它们后面。

因此,如果你需要这种行为,请确保你和其他构建你的项目的人都安装了CMake 3.26或更高版本。
如果由于某种原因不能这样做,解决这个问题的一种方法是切换到使用target_compile_options/add_compile_options来指定语言标准标志(如果需要支持多个编译器,则需要 Package 条件块或生成器表达式),这并不理想,我不建议这样做。您还可以附加到CMAKE_CXX_FLAGS,它会在target_compile_options/add_compile_options添加的内容之前添加。

tyg4sfes

tyg4sfes2#

事实证明,这是一个CMake问题,并在最近的CMake版本中得到了修复。

相关问题