现在,我知道设置编译器标志的现代方法是特定于目标的:
target_compile_options(foo PRIVATE -Werror -Wall -Wextra -pedantic)
target_compile_features(foo PRIVATE cxx_std_17)
这实际上不是最好/最现代的方式。如果您使用的是 CMake 3.19+,最好的办法是创建一个preset https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html.
创建一个名为CMakePresets.json
在你的顶层旁边CMakeLists.txt
包含以下内容:
{
"version": 1,
"cmakeMinimumRequired": {
"major": 3,
"minor": 19,
"patch": 0
},
"configurePresets": [
{
"name": "default",
"displayName": "Default",
"description": "Default build using Ninja",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_CXX_FLAGS": "-Werror -Wall -Wextra -pedantic",
"CMAKE_CXX_STANDARD": "17",
"CMAKE_CXX_STANDARD_REQUIRED": "YES",
"CMAKE_CXX_EXTENSIONS": "OFF"
}
}
]
}
然后配置:
$ cmake --preset=default
The reason以这种方式做事是因为(理想情况下)CMakeLists.txt 中不应该有任何不存在的内容绝对地构建您的项目所需的。警告标志不在该集合中,因此它们属于此处。否则,您会给最终用户带来潜在无效的标志。这在警告标志中非常常见。有些标志仅适用于 GCC 或 Clang,其他标志已被删除或重命名,还有一些标志的敏感性在各个版本之间发生了变化。如果您的用户手动添加-Werror
via CMAKE_CXX_FLAGS
如果您以其他方式添加标志,则可能会出现问题。
这确实意味着对于图书馆,通常适当设置cxx_std_NN
via target_compile_features
, where NN
is the minimum兼容的 C++ 版本(不是首选版本,尽管它们可能一致)的库。这是因为该功能可以在INTERFACE
(相当于。PUBLIC
) 属性,以确保被链接者对库的标题使用足够新的版本。如果两者都CMAKE_CXX_STANDARD
和编译功能已设置,将使用最大值。
在旧版本的 CMake 中,工具链文件 https://cmake.org/cmake/help/latest/manual/cmake-toolchains.7.html可以用于同样的目的。