在我的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
放在任何其他编译标志之前?
2条答案
按热度按时间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>_FLAGS
和CMAKE_<LANG>_FLAGS_<CONFIG>
的语言范围标志之后。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
添加的内容之前添加。tyg4sfes2#
事实证明,这是一个CMake问题,并在最近的CMake版本中得到了修复。