基于现代CMake最佳实践,如何正确启用C++17标准?
嗨,我之前也纠结过这个问题,现代CMake的特性管理确实有点绕,但其实用target_compile_features启用C17的方法和C14是一脉相承的,只是你可能没注意到对应的元特性而已。
直接指定C++17标准(最常用)
从CMake 3.8版本开始,官方提供了一个元特性cxx_std_17,专门用来标记目标需要C17标准。用法和你之前用C14的cxx_std_14完全一致:
# 假设你的目标是可执行文件或库 target_compile_features(my_target PRIVATE cxx_std_17)
这里的PRIVATE表示这个特性只针对当前目标的编译生效;如果是要对外暴露C++17特性的库,就换成PUBLIC或INTERFACE。
CMake会根据你使用的编译器自动生成对应的编译标志——比如GCC/Clang下的-std=c++17,MSVC下的/std:c++17,完全不用你手动写跨平台的编译选项,这正是现代CMake的优势。
更精细的特性指定(按需选择)
如果你不想直接锁定整个C++17标准,而是只用到其中某几个特性(比如std::optional或者结构化绑定),可以直接指定具体的特性标识:
target_compile_features(my_target PRIVATE cxx_optional # C++17特性:std::optional cxx_structured_bindings # C++17特性:结构化绑定 cxx_range_for # 顺便添加一个C++11的特性 )
这种情况下,CMake会自动计算出需要的最低C标准(这里就是C17),然后帮你配置对应的编译选项。这种方式更贴合“只引入需要的特性”的现代CMake理念,不过如果你的代码整体基于C++17编写,直接用cxx_std_17会更省事。
注意事项
- 确保你的CMake版本不低于3.8,
cxx_std_17是从这个版本开始支持的。既然你明确要遵循现代CMake最佳实践,建议升级到3.8及以上版本。 - 如果你想禁用编译器的扩展特性(比如GCC的
gnu++17),可以配合全局设置:
set(CMAKE_CXX_EXTENSIONS OFF)
这样CMake会生成-std=c++17而非-std=gnu++17,保证代码的标准兼容性。
总之,用target_compile_features指定cxx_std_17就是启用C17的正确现代方式,和你之前配置C14的思路完全一致,只是换了对应的特性标识而已。
内容的提问来源于stack exchange,提问作者CD86
相关产品推荐
相关产品推荐

