我有一个包含多个软件组件(可执行文件、库)的代码库(例如存储库)。所有内容都是使用 CMake 构建的,每个组件都有单独的目标。
现在,我知道设置编译器标志的现代方法是特定于目标的:
target_compile_options(foo PRIVATE -Werror -Wall -Wextra -pedantic)
target_compile_features(foo PRIVATE cxx_std_17)
Run Code Online (Sandbox Code Playgroud)
但是,我希望整个项目中的所有目标都具有相同的标志。为每个目标编写这些行会导致代码重复并且容易出错(尤其是当标志数量增加时)。有没有某种方法可以将编译器标志附加到项目而不是目标?
我知道我可以向顶级目录添加选项,如下所示:
add_compile_options(-Werror -Wall -Wextra -pedantic)
Run Code Online (Sandbox Code Playgroud)
但我不确定这是否是正确的方法,而且我也不确定如何对编译功能执行相同的操作(cxx_std_17)。
Ale*_*ing 10
现在,我知道设置编译器标志的现代方法是特定于目标的:
Run Code Online (Sandbox Code Playgroud)target_compile_options(foo PRIVATE -Werror -Wall -Wextra -pedantic) target_compile_features(foo PRIVATE cxx_std_17)
这实际上不是最好/最现代的方式。如果您使用的是 CMake 3.19+,最好的办法是创建一个预设。
创建一个名为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"
}
}
]
}
Run Code Online (Sandbox Code Playgroud)
然后配置:
$ cmake --preset=default
Run Code Online (Sandbox Code Playgroud)
这样做的原因是因为(理想情况下)CMakeLists.txt中不应包含构建项目所必需的任何内容。警告标志不在该集合中,因此它们属于此处。否则,您会给最终用户带来潜在无效的标志。这在警告标志中非常常见。有些标志仅适用于 GCC 或 Clang,其他标志已被删除或重命名,还有一些标志的敏感性在各个版本之间发生了变化。如果您的用户手动添加via并且您以其他方式添加标志,则可能会出现问题。-WerrorCMAKE_CXX_FLAGS
这确实意味着对于库,设置cxx_std_NNvia通常是合适的target_compile_features,其中NN是库的最低兼容 C++ 版本(不是首选版本,尽管它们可能一致)。INTERFACE这是因为可以在(equiv. ) 属性中设置该功能PUBLIC,以确保链接者对库的标头使用足够新的版本。如果两者CMAKE_CXX_STANDARD都设置了,则将使用最大值。
在旧版本的 CMake 中,工具链文件可用于相同的目的。
| 归档时间: |
|
| 查看次数: |
5371 次 |
| 最近记录: |