问题描述
我正在查看 clang 模块的驱动程序测试用例: https://github.com/llvm-mirror/clang/blob/master/test/Driver/modules.cpp
它包括生成 .pcm.o 文件的步骤。我想知道它们是干什么用的。
给定一个 c++20 模块
// a-m.cc
module;
#include <iostream>
export module a;
export void do_a() { std::cout << "A\n"; }
您可以使用
编译它clang++ -std=c++20 -x c++-module --precompile a-m.cc -o a.pcm
来自司机tests:
clang++ -std=c++20 a.pcm -S -o a.pcm.o
.pcm.o 文件的用途是什么?
如果我写一个主程序
// main.cc
import a;
int main() {
do_a();
return 0;
}
编译
clang++ -std=c++20 -c main.cc -fmodule-file=a=a.pcm
然后尝试与 .pcm.o 链接,我得到
clang++ main.o a.pcm.o
/usr/bin/ld:a.pcm.o: file format not recognized; treating as linker script
/usr/bin/ld:a.pcm.o:2: Syntax error
clang-13: error: linker command Failed with exit code 1 (use -v to see invocation)
注意:可以编译a-m.cc
clang++ std=c++20 -c a-m.cc -o a.o
并与 a.o 链接,但是 .pcm.o 文件是做什么用的?预编译后,它们可以用来避免再次编译 a-m.cc 吗?
解决方法
pcm 文件包含关于模块的“半成品”信息。文件扩展名不必是 pcm,我认为例如 Visual Studio 使用 .ifc
作为扩展名。 (与 Visual Studio 的不同之处在于它同时输出 ifc 文件并编译目标文件 (.obj
),而 clang 分两步完成)
pcm 文件以某种格式存储有关模块文件的信息,以便编译器可以轻松地将其导入或编译为其他目标文件。
来自您链接的命令让我感到惊讶,我认为示例中的 -S
正在编译为汇编,所以我很惊讶它列在您链接到的那个 clang 存储库中。
clang++ -std=c++20 a.pcm -S -o a.pcm.o # To mee this looks wrong (assembly output)
尝试将其更改为使用 -c
clang++ -std=c++20 a.pcm -c -o a.pcm.o # This is how you compile pcm-files to object files