什么是 clang 编译的模块 pcm 文件?

rni*_*ckb 5 c++ clang++ c++20 c++-modules

我正在查看 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"; }
Run Code Online (Sandbox Code Playgroud)

您可以使用编译它

clang++ -std=c++20 -x c++-module --precompile a-m.cc -o a.pcm
Run Code Online (Sandbox Code Playgroud)

它生成预编译的模块文件a.pcm

但是也有将 .pcm 文件编译为 .o 文件的步骤。

从驱动程序测试

clang++ -std=c++20 a.pcm -S -o a.pcm.o
Run Code Online (Sandbox Code Playgroud)

如何使用 .pcm.o 文件?

如果我写一个主程序

// main.cc
import a;

int main() {
    do_a();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译

clang++ -std=c++20 -c main.cc -fmodule-file=a=a.pcm
Run Code Online (Sandbox Code Playgroud)

然后尝试与 .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)
Run Code Online (Sandbox Code Playgroud)

注意:可以编译am.cc

clang++ std=c++20 -c a-m.cc -o a.o
Run Code Online (Sandbox Code Playgroud)

并与 ao 链接,但是 .pcm.o 文件是做什么用的?在你预编译之后,它们可以用来避免再次编译 am.cc 吗?

Las*_*öld 1

pcm 文件包含有关模块的“半成品”信息。文件扩展名不必是 pcm,我认为 Visual Studio 例如用作.ifc扩展名。.obj(与 Visual Studio 的区别在于,它同时输出 ifc 文件并编译目标文件 ( ),而 clang 则分两个单独的步骤完成此操作)

pcm 文件以某种格式存储有关模块文件的信息,以便编译器可以轻松导入它或将其编译为其他目标文件。

您链接中的命令让我感到惊讶,我认为-S在示例中正在编译为程序集,所以我很惊讶它列在您链接到的 clang 存储库中。

clang++ -std=c++20 a.pcm -S -o a.pcm.o # To mee this looks wrong (assembly output)
Run Code Online (Sandbox Code Playgroud)

尝试更改它来-c代替使用

clang++ -std=c++20 a.pcm -c -o a.pcm.o # This is how you compile pcm-files to object files
Run Code Online (Sandbox Code Playgroud)