我希望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
用IR生成foo.ll
。-cc1
添加了一些很酷的选项,如-ast-print
。查看-cc1 --help
了解更多详细信息。
要进一步编译LLVM IR以进行汇编,请使用llc
工具:
> llc foo.ll
生成带有程序集的foo.s
(默认为运行它的机器体系结构)。llc
是LLVM工具之一,下面是它的文档。
如果您有多个源文件,您可能实际上想要使用链接时间优化来为整个程序输出一个位代码文件。给出的其他答案将导致您最终为每个源文件生成一个位代码文件。
相反,您希望使用链接时间优化进行编译
clang -flto -c program1.c -o program1.o
clang -flto -c program2.c -o program2.o
对于最后的链接步骤,添加参数-Wl,-plugin-opt=也发出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 -emit-llvm -o foo.bc -c foo.c
clang -o foo foo.bc
如果您有多个文件,并且不想键入每个文件,我建议您遵循以下简单步骤(我使用的是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
。