如何在CMake中指定项目最低C++标准版本适配不同编译器?
在CMake中声明项目至少需要C++11标准(兼容编译器默认更高版本)
针对你的需求——让项目以至少C++11的标准编译,同时保留编译器的默认更高版本(比如GCC 6.3.0默认的C14),而不是强制锁死在C11,这里有一套完全适配Debian打包场景的解决方案:
正确的CMake配置
cmake_minimum_required(VERSION 3.7) project(p CXX) # 禁用GNU扩展,使用纯C++标准(符合Debian打包的ABI一致性要求) set(CMAKE_CXX_EXTENSIONS OFF) add_executable(foobar foobar.cxx) # 声明目标至少需要C++11标准 # CMake会自动处理两种情况: # - 若编译器默认标准 >= C++11:直接使用默认标准(配合EXTENSIONS OFF,会用-std=c++xx而非gnu++xx) # - 若编译器默认标准 < C++11:自动添加-std=c++11参数以满足最低要求 target_compile_features(foobar PRIVATE cxx_std_11)
为什么之前的配置会强制C++11?
你之前使用target_compile_features(foobar PRIVATE cxx_nullptr)时,CMake的逻辑是「为满足单个特性cxx_nullptr,使用支持它的最低标准」——也就是C++11,因此会强制添加-std=c++11参数,完全忽略了编译器默认支持更高版本的情况。
而cxx_std_11是CMake提供的元特性,它的语义是「目标需要至少C11标准」,而非「必须使用C11」。CMake会自动检测编译器的默认标准:只要默认版本不低于C11,就会沿用默认值;只有当默认版本不足时,才会主动升级到C11。
适配Debian打包场景的优势
作为Debian维护者,这种方式完美解决你提到的痛点:
- 避免了显式设置
CMAKE_CXX_STANDARD导致的跨项目标准冲突(比如GDCM与Poppler的版本冲突问题) - 严格遵循Debian官方包的ABI一致性要求,使用编译器默认标准编译
- 自动适配不同GCC版本:
- GCC 4.8.5默认不启用C++11,CMake会自动添加
-std=c++11 - GCC 6.3.0默认启用C14,CMake会保留
-std=c++14(不会强制回退到C11)
- GCC 4.8.5默认不启用C++11,CMake会自动添加
验证方法
执行make VERBOSE=1查看编译命令:
- 在GCC 6.3.0环境下,编译命令会包含
-std=c++14参数 - 在GCC 4.8.5环境下,编译命令会包含
-std=c++11参数
内容的提问来源于stack exchange,提问作者malat
相关产品推荐
相关产品推荐

