如何配置CMake以使用编译器支持的最新C++标准?
自动设置CMake项目为编译器支持的最高C++标准
要实现你的需求——让非头文件库自动使用编译器支持的最高已发布C标准,同时兼容C11,可以通过CMake的try_compile功能手动检测版本,再动态设置编译标准。以下是具体方案:
1. 编写标准检测函数
在CMakeLists.txt中添加一个函数,从最高版本开始向下检测编译器支持的C++标准:
# 检测编译器支持的最高C++标准,结果存入传入的变量 function(detect_highest_cxx_standard OUT_VAR) # 按从新到旧的顺序枚举已发布的C++标准版本 set(cxx_standards 23 20 17 14 11) foreach(standard ${cxx_standards}) # 生成检测代码:仅当当前标准被支持时才能编译通过 set(test_code " #if __cplusplus >= 20${standard}00L || (_MSVC_LANG >= 20${standard}00L && _MSC_VER >= 1910) int main() { return 0; } #else #error Unsupported C++ standard #endif ") # 尝试编译检测代码,判断当前标准是否支持 try_compile( CXX_STANDARD_${standard}_SUPPORTED ${CMAKE_BINARY_DIR}/cxx_std_test SOURCES <STRING>${test_code} CMAKE_FLAGS "-DCMAKE_CXX_STANDARD=${standard}" "-DCMAKE_CXX_STANDARD_REQUIRED=ON" OUTPUT_VARIABLE TEST_OUTPUT ) if(CXX_STANDARD_${standard}_SUPPORTED) set(${OUT_VAR} ${standard} PARENT_SCOPE) return() endif() endforeach() # 保底设置为C++11,确保最低兼容性 set(${OUT_VAR} 11 PARENT_SCOPE) endfunction()
2. 应用检测结果到项目
调用上述函数,将检测到的最高标准设置为项目的编译标准:
# 检测最高支持的C++标准 detect_highest_cxx_standard(HIGHEST_CXX_STANDARD) # 设置项目的C++标准 set(CMAKE_CXX_STANDARD ${HIGHEST_CXX_STANDARD}) set(CMAKE_CXX_STANDARD_REQUIRED ON) # 强制启用该标准的特性 set(CMAKE_CXX_EXTENSIONS OFF) # 禁用编译器特定扩展,保证标准兼容性
3. 处理MSVC的特殊情况
MSVC默认不会正确更新__cplusplus宏的值,需要添加编译选项让其匹配实际使用的标准:
if(MSVC) # 针对你的库目标添加/Zc:__cplusplus选项 target_compile_options(your_library_target PRIVATE "/Zc:__cplusplus") endif()
4. 代码中的宏仍然有效
你原本定义的宏可以保留,因为CMake设置了对应标准后,__cplusplus或_MSVC_LANG会正确反映当前编译标准,宏会自动展开为对应版本的语法:
#if (__cplusplus > 201700L || _MSVC_LANG > 201700L) #define IF_CONSTEXPR_MACRO if constexpr #else #define IF_CONSTEXPR_MACRO if #endif
这样,生成的.so文件会自动使用编译器支持的最高标准编译,同时保证最低兼容C++11,新版特性(如if constexpr)会在条件满足时被启用。
内容的提问来源于stack exchange,提问作者Shawn McAdam
相关产品推荐
相关产品推荐

