mcpField
C
cpp-modules

cpp-modules

github.com/mohitmishra786开发269565 次安装18 周前更新
代码仓库

关于 cpp-modules

cpp-modules 指导 Agent 编写、构建和调试 C++20 模块,涵盖编译器与 CMake 配置,以及和旧式头文件的互操作。

主要功能

  1. 01命名模块与头单元
  2. 02模块分区与实现单元
  3. 03Clang 和 GCC 构建步骤
  4. 04CMake 模块集成
  5. 05常见错误诊断

适用场景

  1. 01设计 C++20 模块结构
  2. 02使用 Clang 或 GCC 构建模块
  3. 03在 CMake 中配置模块
  4. 04诊断导入与 BMI 错误

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill cpp-modules

安装后在 Claude Code 中输入/cpp-modules确认已加载。

附带文件references/modules-cmake-support.md

详细介绍

C++20 模块

用途

指导 Agent 编写、构建和调试 C++20 模块:命名模块与头文件单元、模块分区、CMake 集成、特定于编译器的标志,以及与旧式头文件的互操作。

触发条件

  • “如何编写 C++20 模块?”
  • “如何在 CMake 中导入模块?”
  • “命名模块和头文件单元有什么区别?”
  • “我的模块报错‘找不到模块’”
  • “如何在 Clang 中使用 C++20 模块?”
  • “如何从头文件迁移到模块?”

工作流

1. 模块概念概述
C++20 module kinds:
├── Named module interface unit  (.cppm / .ixx)  — exports declarations
├── Module implementation unit   (.cpp)           — defines module members
├── Module partition             (.cppm)          — internal module subdivision
└── Header unit                  (any header)     — import a legacy header as module

命名模块是主要目标。头文件单元是旧式代码的桥梁。除非需要访问宏,否则避免使用全局模块片段。

2. 命名模块 — 最小示例
// math.cppm — module interface unit
export module math;          // declares the module name

export int add(int a, int b) { return a + b; }
export double pi = 3.14159;

// Non-exported (module-private)
int internal_helper() { return 42; }
// main.cpp — consumer
import math;                 // import the module
#include <iostream>          // legacy header (still works)

int main() {
    std::cout << add(2, 3) << "\n";  // 5
    std::cout << pi << "\n";
}
3. 模块分区
// math-core.cppm — partition
export module math:core;     // partition 'core' of module 'math'

export int add(int a, int b) { return a + b; }
// math.cppm — primary module interface
export module math;
export import :core;         // re-export the partition
// math-impl.cpp — implementation unit (no export)
module math;                 // belongs to 'math' module, not a partition
// has access to all math declarations, but exports nothing
4. 头文件单元 — 衔接旧式头文件
// Import a standard library header as a module unit
import <iostream>;           // header unit (compiler generates BMI)
import <vector>;

// Or import a project header (must be compilable as header unit)
import "myheader.h";

头文件单元不会向导入方提供宏。若要访问宏,请使用全局模块片段:

module;                      // Global Module Fragment starts here
#include <cassert>           // macros like assert() are available
export module mymod;
// ... rest of module
5. 使用 Clang 构建
# Compile module interface → produces .pcm (precompiled module)
clang++ -std=c++20 --precompile math.cppm -o math.pcm

# Compile implementation using the .pcm
clang++ -std=c++20 -fmodule-file=math=math.pcm -c math.cpp -o math.o

# Compile consumer
clang++ -std=c++20 -fmodule-file=math=math.pcm main.cpp math.o -o prog
6. 使用 GCC 构建
# GCC ≥11 supports modules (experimental ≥11, better ≥14)
# Compile interface unit → produces .gcm in gcm.cache/
g++ -std=c++20 -fmodules-ts math.cppm -c -o math.o

# Compiler auto-discovers .gcm files in gcm.cache/
g++ -std=c++20 -fmodules-ts main.cpp math.o -o prog
7. CMake 集成(CMake ≥3.28)
cmake_minimum_required(VERSION 3.28)
project(myproject LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)

add_library(math)
target_sources(math
    PUBLIC
        FILE_SET CXX_MODULES FILES    # module interface units
            src/math.cppm
            src/math-core.cppm
    PRIVATE
        src/math-impl.cpp             # implementation unit
)

add_executable(myapp main.cpp)
target_link_libraries(myapp PRIVATE math)
# Requires a generator that supports modules (Ninja ≥1.11 or MSBuild)
cmake -S . -B build -G Ninja
cmake --build build

对于 CMake 3.25–3.27(实验性):

cmake_minimum_required(VERSION 3.25)
set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP ON)
8. 常见错误
错误原因修复方法
module 'math' not found在搜索路径中找不到 BMI先编译接口单元;检查 -fmodule-file= 标志
cannot import header in module模块作用域内有 #include将 #include 移至全局模块片段,或使用 import <>
redefinition of module 'math'两个 .cppm 文件声明了同一模块每个模块只能有一个主接口
macro not available after import宏不会跨越模块边界将依赖宏的代码移至 GMF,或使用 #include
ODR violation多个分区中存在同名项每个名称只能从一个分区导出
BMI 缓存过期更改后未重新构建 .pcm/.gcm清理构建,或确保依赖跟踪正常工作
9. 与旧式头文件的互操作
// Wrapping a C library for module use
export module cjson;

module;                       // Global Module Fragment
#include <cjson/cJSON.h>      // C header with macros

export module cjson;          // back to module purview

// Re-export key types (optional)
export using ::cJSON;
export using ::cJSON_Parse;

有关 CMake 模块支持的详细信息,请参阅 references/modules-cmake-support.md。

相关技能

  • 使用 skills/build-systems/build-acceleration 将 PCH 作为模块的替代方案
  • 使用 skills/compilers/gcc 或 skills/compilers/clang 查看特定于编译器的模块标志
  • 使用 skills/build-systems/cmake 配置 CMake 项目

评论

支持 Markdown