🌈 C++20特性Modules(一) : 裸编Modules

☀️ 准备工作

首先准备两个文件: import.cpp和mathlib.cpp

// import.cpp源代码
import <iostream>;
import mathlib;

using namespace std;

int main() {
    cout << "Modules, baby!" << endl;
    cout << "2 plus 3 makes " << add(2, 3) << " says module 'mathlib'" << endl;
    return 0;
}
// mathlib.cpp源代码
export module mathlib;

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

两个文件准备好了之后,就需要进行编译:

🍄编译步骤

💥编译mathlib.cpp

首先,编译 mathlib.cpp 以生成模块实现的目标文件。确保使用 -std=c++20-fmodules-ts 标志来启用模块支持。

g++ -std=c++20 -fmodules-ts -c mathlib.cpp -o mathlib.o

解释

-std=c++20:启用 C++20 标准。

-fmodules-ts:启用模块支持(Technical Specification)。

-c:仅编译,不进行链接。

-o mathlib.o:指定输出目标文件为 mathlib.o

💥编译import.cpp

编译 import.cpp,并将之前生成的 mathlib.o 目标文件与之链接,生成最终的可执行文件

g++ -std=c++20 -fmodules-ts import.cpp mathlib.o -o demo

解释

✅同样使用了 -std=c++20-fmodules-ts 标志。

import.cpp 是主程序源文件。

mathlib.o 是之前编译的模块目标文件。

-o demo 指定输出的可执行文件名为 demo

运行上述命令,这个时候会报错:

In module imported at import.cpp:1:1:
/home/opt/compiler/gcc-12/include/c++/12.1.0/iostream: error: failed to read compiled module: No such file or directory
/home/opt/compiler/gcc-12/include/c++/12.1.0/iostream: note: compiled module file is ‘gcm.cache/./home/opt/compiler/gcc-12/include/c++/12.1.0/iostream.gcm’
/home/opt/compiler/gcc-12/include/c++/12.1.0/iostream: note: imports must be built before being imported
/home/opt/compiler/gcc-12/include/c++/12.1.0/iostream: fatal error: returning to the gate for a mechanical issue
compilation terminated.

原因分析

这个错误主要是因为 G++ 12.1.0 对 C++20 模块的支持尚不完善,特别是标准库(如 <iostream>)的模块化支持。具体原因如下:

  1. 标准库模块化支持不完整:GCC 12.1.0 并未预先编译标准库的模块文件(如 iostream.gcm),因此在 import <iostream>; 时,编译器找不到相应的已编译模块文件。
  2. GCC 的模块支持处于实验阶段:虽然 GCC 从版本 10 开始引入了对 C++20 模块的支持,但在 12.1.0 版本中,这一支持仍然不够成熟,存在诸多限制和已知问题。

解决方案是修改import.cpp, 标准库还是采用传统的include方式引入,之后再运行第二步命令行就可以生成demo可执行文件。

// import.cpp源代码
#include <iostream>   // 使用 #include 代替 import
import mathlib;

using namespace std;

int main() {
    cout << "Modules, baby!" << endl;
    cout << "2 plus 3 makes " << add(2, 3) << " says module 'mathlib'" << endl;
    return 0;
}

💥 运行生成的可执行文件

编译成功后,运行程序以验证输出:

$ ./demo

Modules, baby!
2 plus 3 makes 5 says module 'mathlib'

📱 联系方式

更多文章或咨询关注:微信公众号(pwfocus) 项目合作加个人微信
pwfocus 个人微信