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

What are clang's compiled module pcm files for?

我正在查看 clang 模块的 driver 测试用例: 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

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

不过也有将.pcm文件编译成.o文件的步骤

来自driver 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

然后尝试 link 与 .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

和 link 与 a.o,但是 .pcm.o 文件有什么用?是否可以使用它们来避免在预编译后再次编译 a-m.cc?

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

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

来自你的 link 的命令让我感到惊讶,我认为示例中的 -S 正在编译为汇编,所以我很惊讶它被列在你 link编辑到。

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