1. 为什么使用 Modules

模块(Modules)是 C++20 引入了一个重要的新特性,解决头文件(如编译速度慢、宏污染、重复包含、依赖管理混乱等问题。使用体验上更现代,和其他语言类似。所以使用modules一是为了体验新特性的使用,学习c++ 新标准,也是为了以后项目迁移做准备。

2. 项目搭建

2.1 工程结构

在这里插入图片描述

2.2 代码编写

io.cppm :

export module io;

export void print_result(const char* label, int value);

io_impl.cpp:

module;                  // 开启全局模块段
#include <iostream>      // 实现中使用标准库也需要前置包含

module io;               // 指定所属模块

void print_result(const char* label, int value) {
    std::cout << label << value << std::endl;
}

这里 module 用于开启全局模块段, 在兼容导入原始头文件时使用,在实现中使用标准库也需要前置包含。module io, 用于指定所属模块。
math.cppm:

export module math;                // 声明并导出模块

export int add(int a, int b);      // 导出函数声明
export int multiply(int a, int b); // 另一个导出函数

math_impl.cpp:

module math;  // 指定所属模块

int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

main.cpp:

import std;

import io;    // 导入IO模块
import math;  // 导入数学模块

int main() {
    std::println("Use std module on {}", "hello");
    
    int sum = add(3, 4);       // 使用模块导出函数
    int product = multiply(3, 4);
    print_result("Sum:    ", sum);
    print_result("Product:", product);
    return 0;
}

import std, 是c++ 23提供的modules 标准库模块。 std::println(“Use std module on {}”, “hello”); 是c++ 23 提供的插值表达式。

3. cmakelist.txt 配置

要使用c++ 23 import std 支持需要比较新的编译器和cmke版本支持,构建工具使用ninja, make 目前不支持。环境搭建和工具安装参考前面章节。

3.1 查看 CMAKE_EXPERIMENTAL_CXX_IMPORT_STD 值

地址:https://github.com/Kitware/CMake/blob/v4.2.0/Help/dev/experimental.rst
根据自己cmake版本来查询对应的版本, 此提供很多支持。
在这里插入图片描述

类别 特性 核心用途
C++ 语言特性 C++ import std support 启用 C++23 标准库模块导入。
包管理 Export Package Dependencies 自动导出包的依赖关系,方便下游使用。
包管理 Export CPS Package Information 以标准化的 CPS 格式导出包元数据。
包管理 Find/Import CPS Packages 支持查找符合 CPS 规范的包。
构建工具集成 Build database support 导出构建信息数据库,供 IDE 和分析工具使用。
高级构建分析 Instrumentation 在构建过程中插入自定义逻辑,收集额外数据。

如果只使用 import std 只需要引入对应的就行,这里为了方便,直接导入全部。

3.2 Cmakelist.txt 编写

cmake_minimum_required(VERSION 4.2.0)

set(CMAKE_CXX_MODULE_STD ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS ON)

# 启用 C++23 标准库模块导入
set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD  "d0edc3af-4c50-42ea-a356-e2862fe7a444")
# 自动导出包的依赖关系,方便下游使用
set(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_DEPENDENCIES  "1942b4fa-b2c5-4546-9385-83f254070067")
# 以标准化的 CPS 格式导出包元数据
set(CMAKE_EXPERIMENTAL_EXPORT_PACKAGE_INFO  "b80be207-778e-46ba-8080-b23bba22639e")
# 支持查找符合 CPS 规范的包
set(CMAKE_EXPERIMENTAL_FIND_CPS_PACKAGES  "e82e467b-f997-4464-8ace-b00808fff261")
# 导出构建信息数据库,供 IDE 和分析工具使用
set(CMAKE_EXPERIMENTAL_EXPORT_BUILD_DATABASE  "73194a1d-c0b5-41b9-9190-a4512925e192")
# 在构建过程中插入自定义逻辑,收集额外数据
set(CMAKE_EXPERIMENTAL_INSTRUMENTATION  "ec7aa2dc-b87f-45a3-8022-fe01c5f59984")


project(app LANGUAGES CXX)

# 生成 compile_command.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(TARGET app)


############## 模块配置 ##############################################
# 创建数学模块库
add_library(math_mod)
target_sources(math_mod
    PUBLIC
        # 模块接口文件集
        FILE_SET cxx_modules TYPE CXX_MODULES
            BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/math
            FILES src/math/math.cppm
    
    PRIVATE
        # 实现文件
        src/math/math_impl.cpp
)

# io 模块
add_library(io_mod)
target_sources(io_mod
    PUBLIC
        # 模块接口文件集
        FILE_SET cxx_modules TYPE CXX_MODULES
            BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/io
            FILES src/io/io.cppm
    
    PRIVATE
        # 实现文件
        src/io/io_impl.cpp
)



############## 三方库配置 #############################################

############### 项目配置 ##############################################
# 头文件
include_directories(${CMAKE_SOURCE_DIR}/include)

# 源文件
file(GLOB SRC_FILES
    ${CMAKE_SOURCE_DIR}/src/*.cpp
)

# 创建主程序
add_executable(${TARGET} src/app/main.cpp)
target_link_libraries(${TARGET} PRIVATE math_mod io_mod)

3.3 项目编译配置

这里使用llvm-mingw, 使用mingw 测试编译有问题, 编译器下载及环境安装参考之前章节。

  • 项目配置: .vscode/settings.json
{
    "cmake.generator": "Ninja",
    "clangd.path": "C:/software/llvm-mingw-20251118-ucrt-x86_64/bin/clangd.exe",
    "clangd.arguments": [
        "--compile-commands-dir=${workspaceFolder}/build",
        "--query-driver=C:/software/llvm-mingw-20251118-ucrt-x86_64/bin/g++.exe",
        "--log=verbose",
        "--pretty",
        "--all-scopes-completion",
        "--completion-style=bundled",
        "--cross-file-rename",
        "--header-insertion=never",
        "--background-index",
        "--clang-tidy",
        "--clang-tidy-checks=cppcoreguidelines-*,performance-*,bugprone-*,portability-*,modernize-*,google-*",
        "-j=2",
        "--pch-storage=disk",
        "--function-arg-placeholders=false",
        "--experimental-modules-support"
    ]
}

上述项目配置会有些提示,忽略就可以:
在这里插入图片描述

4. 编译运行测试

选择编译器:
ctrl + shift + p 后选择 CMake: Select a Kit
在这里插入图片描述
选择之前安装的最新版llvm-mingw:
在这里插入图片描述
点击左下角编译运行:
在这里插入图片描述

  • 测试结果:
    在这里插入图片描述
  • 如果出现编译通过, vscode 代码提示 import 未找到或者不能识别的问题,检查clangd插件环境,尝试重启vscode, 重新编译来解决。

5. 代码

https://gitcode.com/CodingBinary/vulkan-st-log/tree/main/03cpp_modules

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐