Clang(含Xcode 9.3 beta及7.0.0 trunk)下C++ Module TS使用遇阻
解决Clang下C++ Module TS的链接与模块识别问题
我之前在Clang上折腾C++ Module TS的时候也踩过几乎一模一样的坑,给你梳理下亲测有效的操作步骤,应该能解决你的问题:
先确认模块文件结构是否正确
首先要保证module.cppm的开头正确声明导出模块,比如假设你的模块叫mymodule,文件内容应该是这样:
export module mymodule; export void whatever() { // 这里是你的函数实现 }
而main.cpp里要正确导入模块:
import mymodule; int main() { whatever(); return 0; }
正确的编译流程(解决链接错误)
你遇到的whatever()未找到链接错误,大概率是因为只编译了模块的预编译文件(.pcm),但没有把模块的实现代码链接进最终程序。按以下步骤操作:
编译模块生成预编译文件(.pcm)和目标文件(.o)
# 同时生成预编译模块文件和模块目标文件 clang++ -std=c++20 -fmodules-ts -c module.cppm -o module.o -Xclang -emit-module -Xclang -emit-module-path=module.pcm这条命令一次性生成模块的实现目标文件
module.o和预编译模块文件module.pcm,不用分开执行两次编译。编译并链接main.cpp
编译main的时候,需要指定模块的预编译文件,同时链接模块的目标文件:clang++ -std=c++20 -fmodules-ts -fmodule-file=mymodule=module.pcm main.cpp module.o -o main这里的
mymodule必须和你在module.cppm里声明的模块名完全一致,Clang通过这个名字关联对应的预编译文件。
用-fprebuilt-module-path的正确姿势(解决未知模块报错)
如果想用-fprebuilt-module-path=.替代-fmodule-file,需要满足一个关键前提:预编译模块文件的文件名必须和模块名完全一致。比如模块名是mymodule,那你要把生成的pcm文件重命名为mymodule.pcm,然后执行:
- 重新生成命名正确的pcm文件:
clang++ -std=c++20 -fmodules-ts -c module.cppm -o module.o -Xclang -emit-module -Xclang -emit-module-path=mymodule.pcm - 编译并链接main:
这样Clang会自动在当前目录(clang++ -std=c++20 -fmodules-ts -fprebuilt-module-path=. main.cpp module.o -o main.)下搜索名为mymodule.pcm的预编译文件,就不会报未知模块的错误了。
额外注意事项
- Xcode 9.3 beta自带的Clang版本比较老旧,对C++ Module TS的支持有不少bug,建议优先用最新的7.0.0 trunk版本测试,能避开很多兼容性问题。
- 可以用
clang++ -v确认你的Clang版本,同时确保添加-fmodules-ts参数时不会出现不支持的报错。
内容的提问来源于stack exchange,提问作者MrMobster
相关产品推荐
相关产品推荐

