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

问题描述

我正在查看 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

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

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

来自司机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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...