在 CMakeLists.txt 中设置 C++23 标准

1. 引言

随着 C++ 标准的不断演进,C++23 引入了许多新特性和改进,如 std::expected、std::print、std::mdspan 等。要在你的 C++ 项目中使用这些新特性,首先需要在构建系统中正确配置 C++23 标准。CMake 是目前最流行的跨平台构建系统之一,本文将详细介绍如何在 CMakeLists.txt 文件中设置 C++23 标准。

2. 设置 C++ 标准的方法

CMake 提供了多种方式来指定 C++ 标准,以下是几种常用方法,从现代到传统排序。

2.1 使用 target_compile_features(推荐)

这是最现代、最推荐的方式,它允许你为特定的目标(可执行文件或库)指定所需的 C++ 特性,CMake 会自动推导出所需的最低标准版本。

cmake 复制代码
cmake_minimum_required(VERSION 3.20)
project(MyProject)
add_executable(my_app main.cpp)
为 my_app 目标启用 C++23 标准
target_compile_features(my_app PRIVATE cxx_std_23)

优点:语义清晰,与目标绑定,CMake 会自动处理兼容性。

注意 :需要 CMake 3.20 或更高版本才能识别 cxx_std_23。

2.2 使用 set_target_properties 设置 CXX_STANDARD

你可以直接为目标设置 CXX_STANDARD 属性。

cmake 复制代码
cmake_minimum_required(VERSION 3.8)
project(MyProject)
add_executable(my_app main.cpp)
设置 my_app 目标使用 C++23 标准
set_target_properties(my_app PROPERTIES
CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)

参数解释:

  • CXX_STANDARD 23:指定使用 C++23 标准。
  • CXX_STANDARD_REQUIRED ON:要求编译器必须支持 C++23,否则配置失败。
  • CXX_EXTENSIONS OFF:禁用编译器扩展(如 GNU 扩展),确保使用标准的 ISO C++。

2.3 使用全局变量 CMAKE_CXX_STANDARD

如果你希望项目中所有目标都使用同一个 C++ 标准,可以设置全局变量。

cmake 复制代码
cmake_minimum_required(VERSION 3.1)
project(MyProject)
为项目中所有目标设置 C++23 标准
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
add_executable(my_app main.cpp)
add_library(my_lib STATIC lib.cpp)

注意:此设置会影响之后定义的所有目标。

3. 检查编译器支持

并非所有编译器都完全支持 C++23。你可以在 CMakeLists.txt 中添加检查,或在配置时给出提示。

cmake 复制代码
# 检查编译器是否声称支持 C++23
include(CheckCXXCompilerFlag)
check_cxx_compiler_flag("-std=c++23" COMPILER_SUPPORTS_CXX23)
if(COMPILER_SUPPORTS_CXX23)
message(STATUS "编译器支持 C++23")
else()
message(WARNING "当前编译器可能不支持完整的 C++23 标准,某些特性可能不可用。")
endif()

4. 完整示例

下面是一个完整的 CMakeLists.txt 示例,演示了如何为一个简单的项目设置 C++23 标准。

cmake 复制代码
cmake_minimum_required(VERSION 3.20)
project(MyCpp23Project VERSION 1.0.0 LANGUAGES CXX)
方法1:全局设置(可选,与方法2任选其一)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
添加可执行文件
add_executable(my_app main.cpp)
方法2:为目标设置(推荐)
target_compile_features(my_app PRIVATE cxx_std_23)
或者使用 set_target_properties
set_target_properties(my_app PROPERTIES
CXX_STANDARD 23
CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)
可选:添加包含目录、链接库等
target_include_directories(my_app PRIVATE include)
target_link_libraries(my_app PRIVATE some_library)

5. 常见问题与解决

5.1 配置失败,提示 "Cannot specify compile features for target ..."

原因 :target_compile_features 需要在 add_executable 或 add_library 之后调用。

解决:确保调用顺序正确。

5.2 编译器报错,不认识 C++23 特性

可能原因:

  1. 编译器版本过低(如 GCC < 13, Clang < 16, MSVC < 19.34)。
  2. CMake 生成的编译命令未正确包含 -std=c++23 标志。

解决:

  • 升级编译器。
  • 检查 CMake 生成的构建文件(如 build.ninja 或 Makefile),确认是否有 -std=c++23 标志。
  • 尝试显式设置编译标志(不推荐,可能破坏跨平台性):target_compile_options(my_app PRIVATE -std=c++23)

5.3 我想同时支持 C++17 和 C++23 怎么办?

通常为整个项目选择一个标准。如果库需要支持多标准,可以考虑使用条件编译或提供不同的构建目标。

6. 总结

在 CMakeLists.txt 中设置 C++23 标准主要有三种方式:

  1. (最推荐) 使用 target_compile_features(my_target PRIVATE cxx_std_23),需要 CMake 3.20+。
  2. 使用 set_target_properties 设置 CXX_STANDARD 等属性。
  3. 设置全局变量 CMAKE_CXX_STANDARD。

建议始终设置 CXX_STANDARD_REQUIRED ON 和 CXX_EXTENSIONS OFF 以确保严格的标准符合性和可移植性。配置后,即可在代码中安全地使用 C++23 的新特性。

相关推荐
阿俊-全栈开发3 小时前
LikeShop 单商户SaaS商城分销模块二开:佣金计算与结算逻辑实现
java·开发语言·微服务·likeshop·likeshop开源商城·likeshop多商户
夜听莺儿鸣6 小时前
502-002_Linux驱动开发模块化编程
linux·驱动开发·模块化编程
wuminyu6 小时前
C++协程实现接收端的零拷贝Buffer管理原理剖析
java·linux·c语言·jvm·c++
科力锐品牌君7 小时前
应用级灾备 | 海量非结构化数据如何实现高效数据保护
linux·运维·网络·安全·系统安全·数据安全·灾备
zhangrelay7 小时前
ROS项目设计案例智能大模型正经乱答案例
linux·笔记·学习·ubuntu·机器人
流浪0018 小时前
Linux系统篇39——线程(四) pthread库的由来和线程的创建与等待
linux·操作系统·线程·pthread库
Lancker8 小时前
chnroute-linux — 中国大陆 IP 段每日自动更新 + 「仅允许国内访问」落地
linux·运维·tcp/ip
蜗牛互联网9 小时前
WSL Containers GA:本地AI容器的生命周期、网络与治理验收
java·网络·人工智能·后端
高山有多高9 小时前
【Linux笔记】Linux进程与守护进程
linux
龙亘川9 小时前
铭记英烈守初心,数字强基促服务:亘川智城退役军人服务系统的实践与价值
java·数据库·人工智能