我希望 clang 将我的 C/C++ 代码编译为 LLVM 位码,而不是二进制可执行文件。我怎样才能做到这一点?
如果我有 LLVM 位码,如何进一步将其编译为二进制可执行文件?
在编译为二进制可执行文件之前,我想将一些我自己的代码添加到 LLVM 位码。
给定一些 C/C++ 文件foo.c
:
> clang -S -emit-llvm foo.c
生成foo.ll
LLVM IR 文件。
该-emit-llvm
选项也可以直接传递给编译器前端,而不是通过以下方式传递给驱动程序-cc1
:
> clang -cc1 foo.c -emit-llvm
foo.ll
使用 IR生成。-cc1
添加了一些很酷的选项,例如-ast-print
. 查看-cc1 --help
更多详情。
要进一步编译 LLVM IR 以进行组装,请使用以下llc
工具:
> llc foo.ll
与装配一起生产foo.s
(默认为您运行它的机器架构)。llc
是 LLVM 工具之一 -这是它的文档。
采用
clang -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
如果您有多个源文件,您可能实际上想要使用链接时间优化来为整个程序输出一个位码文件。给出的其他答案将导致您最终得到每个源文件的位码文件。
相反,您希望使用链接时间优化进行编译
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
对于最后的链接步骤,添加参数 -Wl,-plugin-opt=also-emit-llvm
clang -flto -Wl,-plugin-opt=also-emit-llvm program1.o program2.o -o program
这为您提供了一个已编译的程序和与之对应的位码(program.bc)。然后,您可以以任何您喜欢的方式修改 program.bc,并随时重新编译修改后的程序
clang program.bc -o program
尽管请注意,您需要在此步骤再次包含任何必要的链接器标志(用于外部库等)。
请注意,您需要使用黄金链接器才能正常工作。如果您想强制 clang 使用特定的链接器,请在计算机上某个名为“fakebin”的特殊目录中创建一个指向该链接器的符号链接,名为“ld”,然后添加选项
-B/home/jeremy/fakebin
到上面的任何链接步骤。
如果您有多个文件并且不想键入每个文件,我建议您按照以下简单步骤操作(我正在使用clang-3.8
,但您可以使用任何其他版本):
生成所有.ll
文件
clang-3.8 -S -emit-llvm *.c
将它们链接成一个
llvm-link-3.8 -S -v -o single.ll *.ll
(可选)优化你的代码(也许是一些别名分析)
opt-3.8 -S -O3 -aa -basicaaa -tbaa -licm single.ll -o optimised.ll
生成程序集(生成optimised.s
文件)
llc-3.8 optimised.ll
创建可执行文件(命名a.out
)
clang-3.8 optimised.s
你读过clang
文档吗?您可能正在寻找-emit-llvm
.