6. c++ 20 Modules 使用

文章目录

  • [1. 为什么使用 Modules](#1. 为什么使用 Modules)
  • [2. 项目搭建](#2. 项目搭建)
    • [2.1 工程结构](#2.1 工程结构)
    • [2.2 代码编写](#2.2 代码编写)
  • [3. cmakelist.txt 配置](#3. cmakelist.txt 配置)
    • [3.1 查看 CMAKE_EXPERIMENTAL_CXX_IMPORT_STD 值](#3.1 查看 CMAKE_EXPERIMENTAL_CXX_IMPORT_STD 值)
    • [3.2 Cmakelist.txt 编写](#3.2 Cmakelist.txt 编写)
    • [3.3 项目编译配置](#3.3 项目编译配置)
  • [4. 编译运行测试](#4. 编译运行测试)
  • [5. 代码](#5. 代码)

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

相关推荐
沐浴露z1 小时前
详解Java ArrayList
java·开发语言·哈希算法
x***B4111 小时前
Rust unsafe代码规范
开发语言·rust·代码规范
北郭guo1 小时前
Java设计模式 【理论+代码实现】 让你从小白到大佬的蜕变
java·开发语言·设计模式
MediaTea1 小时前
Python 库手册:gc 垃圾回收
java·开发语言·jvm·python·算法
j***12151 小时前
java进阶1——JVM
java·开发语言·jvm
JienDa3 小时前
JienDa聊PHP:小红书仿站实战深度架构全解析
开发语言·架构·php
执笔论英雄7 小时前
Slime异步原理(单例设计模式)4
开发语言·python·设计模式
止观止9 小时前
C++20 Concepts:让模板错误信息不再“天书”
c++·c++20·编程技巧·模板编程·concepts
e***74959 小时前
Modbus报文详解
服务器·开发语言·php