使用g++编译cpp20的module文件


简介

简单记录一下初次尝试c++20中module特性的过程。包括一个main.cpp和子模块 test_include.cxx。编译器为gnu的g++12.2。编译环境是wsl2-arch,glibc>=2.36(g++12.2要求的)。

demo结构

两个文件,main.cpp 和 子模块 test_include.cxx。直接上代码:

“ main.cpp ”

1import TestInclude;//引入TestInclude模块
2
3int main(){
4 TestInclude::push(1);// 这个TestInclude是命名空间的名字,不是模块名!!!
5 TestInclude::push(3);
6 TestInclude::push(2);
7 TestInclude::print();
8 // std::cout << "error\n"; //美滋滋地把std::cout 隐藏起来, 如果用include这个cout会自动引入
9 return 0;
10}

“ test_include.cxx ”

1//本模块定义一个私有的全局vector,对外导出两个接口,push和print
2module;//这一行不能少!
3#include<vector>
4#include<iostream>
5
6export module TestInclude; //声明一下模块名字
7
8std::vector<int32_t> staticVec;//
9
10export namespace TestInclude{//导出接口外边套一层namespace
11 void push(int32_t x){
12 staticVec.push_back(x);
13 }
14
15 void print(){
16 for (auto x:staticVec){
17 std::cout << x << ' ';
18 }
19 std::cout << '\n';
20 }
21}

编译运行

编译命令 1g++ test_include.cxx main.cpp -o o -std=c++20 -fmodules-ts

执行1./o 可以如期输出11 3 2

总结

  • 编译命令需要添加1-std=c++201-fmodules-rs。现在g++编译错误提示还可以,1-fmodule-ts我现在还不知道为什么
  • main.cpp是找不到std::cout的,这种module的特性应该大有可为!!封装c库?
  • test_include.cxx 中手动控制了模块名和一个默认导出的命名空间同为1TestInclude,算是强行伪装了rust中文件名即模块名的特点。利用一个默认导出的命名空间可以规范模块导出的接口,这个意义更为重要,估计会出现在很多编码规范中!(或者限制在某一个命名空间中导出,效果类似,个人更倾向上边这种,export个数少)
  • g++还可以使用1g++ -c -xc++ test_include.cxx -fmodules-ts单独编译某个模块。会生成1gcm.cache/TestInclude.gcm1test_include.o的缓存文件,据说可以加快编译速度。emmm期待编译工具链的支持。