炸裂!C++23 模块与 CMake 碰撞出的新特效编程魔法
解决 CLion 中 import std 无法识别导航的问题
使用 C++20 Modules 导入 Boost 模块的方法
引言
在 C++ 的浩瀚编程宇宙里,C++23 宛如一颗耀眼新星,它在 C++20 模块特性的基础上,又进一步释放出了令人惊叹的能量,带来更高效的编译体验和更清晰的代码组织方式。而 CMake 这位跨平台构建的“魔法大师”,能与 Clang、MSVC 等编译器携手,共同为开发者打造出一个梦幻般的编程世界。接下来,就让我们一同揭开在 CMake 项目中使用 C++23 模块的神秘面纱,领略其中关键配置与代码示例的独特魅力。
环境准备
在开启这场编程冒险之前,你得先确保自己的“装备”齐全:
- 编译器:
- Clang:需使用 Clang 17 及以上版本以及ninja 1.11.1版本
- MSVC:要使用 MSVC 的最新版本
- CMake:CMake 版本得在 3.30 及以上
CMake 关键配置
1. 启用 C++23 模块支持(编译器适配)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17)
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
set(CMAKE_CXX_MODULE_STD ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# MSVC 最新版本对 C++23 模块的相关设置,目前 MSVC 可能不需要特定 UUID 及类似 Clang 的部分设置
set(CMAKE_CXX_MODULE_STD ON)
endif()
这里运用 if - elseif 语句进行精准判断,就像一位精明的探险家在选择正确的道路。要是你使用的是 Clang 编译器,并且版本大于等于 17,就可以开启特定的设置。CMAKE_EXPERIMENTAL_CXX_IMPORT_STD 就像是一把神奇的钥匙,能帮你打开标准库模块的大门;CMAKE_CXX_MODULE_STD 开启了 C++ 标准库模块的支持,如同为你的飞船启动了强大的引擎;CMAKE_CXX_FLAGS 添加 -stdlib=libc++ 标志,指定使用 libc++ 标准库,这在使用 import std 时可是必不可少的魔法咒语。而对于 MSVC 最新版本,开启 CMAKE_CXX_MODULE_STD 即可开启标准库模块支持。
2. 通用设置
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_EXTENSIONS ON)
CMAKE_CXX_STANDARD:指定使用 C++23 标准CMAKE_CXX_STANDARD_REQUIRED:确保项目必须使用指定的 C++ 标准进行编译CMAKE_CXX_SCAN_FOR_MODULES:开启模块扫描功能CMAKE_EXPORT_COMPILE_COMMANDS:导出编译命令,方便其他工具(如 IDE)使用CMAKE_CXX_EXTENSIONS:开启编译器扩展,目前在使用import std时这是必需的
3. 设置模块代码
target_sources(asio_blog
PUBLIC
FILE_SET core_cxx_modules TYPE CXX_MODULES FILES
${MODULES_FILES}
)
target_sources这个神奇的指令,用于为目标asio_blog添加源文件。这里使用FILE_SET指定了一个名为core_cxx_modules的 C++ 模块文件集,TYPE CXX_MODULES明确这些文件是 C++ 模块文件,${MODULES_FILES}是包含模块文件路径的变量,就像是把一颗颗璀璨的宝石收集到一起,组成一个强大的魔法阵。
4. 分离模块生成与编译
set_property(TARGET asio_blog PROPERTY
CXX_MODULE_GENERATION_MODE "SEPARATE"
)
set_property为目标asio_blog设置属性。CXX_MODULE_GENERATION_MODE "SEPARATE"表示采用分离模式生成模块,这种模式下模块的生成和编译是分开进行的,就像是把复杂的魔法仪式拆分成不同的步骤,有助于提高编译效率,让你的编程魔法施展得更加迅速。
完整 CMakeLists.txt 示例
cmake_minimum_required(VERSION 3.30)
project(AsioBlogProject)
# 启用 C++23 模块支持(编译器适配)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 17)
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD "0e5b6991-d74f-4b3d-a41c-cf096e0b2508")
set(CMAKE_CXX_MODULE_STD ON)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_MODULE_STD ON)
endif()
# 通用设置
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_EXTENSIONS ON)
# 定义模块文件列表
set(MODULES_FILES
module1.cppm
module2.cppm
)
# 添加可执行目标
add_executable(asio_blog main.cpp)
# 设置模块代码
target_sources(asio_blog
PUBLIC
FILE_SET core_cxx_modules TYPE CXX_MODULES FILES
${MODULES_FILES}
)
# 分离模块生成与编译
set_property(TARGET asio_blog PROPERTY
CXX_MODULE_GENERATION_MODE "SEPARATE"
)
C++ 模块代码示例
模块文件 module1.cppm
export module module1;
import std;
export namespace module1_ns {
void hello() {
std::cout << "Hello from module1!" << std::endl;
}
}
主文件 main.cpp
import module1;
import std;
int main() {
module1_ns::hello();
return 0;
}
编译和运行项目
Clang 编译
在项目根目录下,执行以下命令进行编译和运行:
mkdir build
cd build
cmake -DCMAKE_CXX_COMPILER=clang++ ..
cmake --build .
./asio_blog
MSVC 编译
若使用 MSVC,在项目根目录下,打开开发人员命令提示符,执行以下命令:
mkdir build
cd build
cmake -G "Visual Studio XX" ..
cmake --build . --config Release
Debug\asio_blog.exe # 根据实际配置选择 Debug 或 Release 目录下的可执行文件
总结
通过以上步骤,你就能在 CMake 项目中轻松使用 C++23 模块,无论是 Clang 还是 MSVC 最新版本编译器都能完美适配,感受它们碰撞出的编程新特效。合理运用 CMake 的相关配置和 C++23 模块特性,能显著提高项目的编译效率和代码的可维护性。如果你想了解更多关于 CMake 中 import std 的信息,可以参考 CMake 官方博客:https://www.kitware.com/import-std-in-cmake-3-30/。希望你能在这场编程冒险中收获满满,创造出属于自己的编程奇迹!
2438

被折叠的 条评论
为什么被折叠?



