LLVM-Clang编译器安装和使用

LLVM不仅仅是一个编译器,同时提供了模块化的功能和库,用于编译器的开发和功能扩展。常规的一个编译器分为前端、优化器和后端,LLVM编译器也不例外,Clang就是属于一个编译器的前端部分,LLVM属于优化器和后端,当然LLVM也可以支持其他类型的前端,比如GCC前端编译器。

Clang的安装

  • apt安装

本文介绍到的LLVM-Clang就是使用Clang前端的LLVM编译器,一般情况下LLVM都会说使用Clang作为前端,Clang是专为LLVM而开发的,所以这是最佳的搭配。在ubuntu系统上安装:

sudo apt-get install clang
sudo apt-get install llvm

要注意的是clang和llvm实际上是两个东西,llvm类似于一个容器,可以使用clang作为前端插件,也可以使用其他类型的前端插件,因此我们需要安装两个。

  • 官网下载整包安装

在llvm的官网 http://clang.llvm.org/get_started.html 可以查看已经编译好的各个平台的release版本,Clang也会作为llvm release的一部分一起发布:http://releases.llvm.org/

  • 源码编译安装

参考官网 http://clang.llvm.org/get_started.html 上的步骤,其实也很简单,下载源码后配置一下cmake,编译、安装即可。

Clang的使用

LLVM(low level virtual machine)顾名思义它是一种虚拟机,它在对代码进行处理的时候都需要使用IR中间文件,所以源代码要被先转换为LLVM IR中间文件(LLVM Intermediate Representation)。

LLVM在对程序进行优化的时候全部都是以IR的形式来进行优化的,它类似于是一种被LLVM所使用的一种语言,可以跨平台使用,因此所有平台上的LLVM都可以解释同一份IR,然后LLVM后端再利用IR生成不同平台上的机器码,此种类型的程序才可以正常运行。

LLVM IR文件(文本形式)

生成文本格式的IR文件:

clang -O3 -emit-llvm helloworld.c -S -o helloworld.ll

LLVM IR文件(二进制形式)

直接编译生成二进制格式IR文件:

clang -O3 -emit-llvm helloworld.c -c -o helloworld.bc

LLVM IR文件格式转换

.bc和.ll文件的转换:

llvm-as helloworld.ll     //llvm .ll -> .bc assembler
llvm-dis helloworld.bc  //llvm .bc -> .ll disassembler

LLVM IR生成平台对应的汇编文件
通过IR文件生成符合目标平台上的汇编文件,LLVM后端做的事情,通过llc进行操作:

llc helloworld.ll -o helloworld.S

LLVM IR生成平台对应的可执行文件

通过IR文件生成符合目标平台上的可执行文件,LLVM后端做的事情,通过llc进行操作:


llc -filetype=obj helloworld.ll -o helloworld.o
gcc helloworld.o

或者

llc -filetype=obj helloworld.bc -o helloworld.o
gcc helloworld.o

llvm只能保证生成obj文件,最后都需要使用gcc进行一次链接才能生成可执行文件。
LLVM IR文件link操作

llvm-link func1.bc func2.bc -o linked.bc

交叉编译

交叉编译arm64平台andoird native程序

clang -O3 -emit-llvm helloworld.c -c -target aarch64-none-linux-android -o helloworld.bc   # 生成aarch64-none-linux-android目标的IR文件
clang -O3 -emit-llvm helloworld.c -S -target aarch64-none-linux-android -o helloworld.ll     # 生成aarch64-none-linux-android目标的IR文件
llc -march=aarch64 helloworld.bc -o hello.S                   #生成aarch64平台上的汇编文件
llc -march=aarch64 -filetype=obj helloworld.bc -o hello.o  #生成aarch64平台上的obj文件

注意到这里生成的hello.o并不是一个可执行文件,最后一步需要调用本地链接器链接后才可以生成最终的可执行文件。

aarch64-linux-android-gcc hello.o  #生成最后的a.out可执行文件

参考文档:
https://zhuanlan.zhihu.com/p/66793637
https://llvm.org/docs/LangRef.html
https://llvm.org/

你可能感兴趣的:(编译)