安装原文:https://www.jianshu.com/p/861c1a630059
(为方便查看,把要点复制过来了)
准备工作
首先安装必要的软件,官方是使用 svn 进行版本控制的,我们可以通过 svn 获取其源码。安装过程中要用到 cmake 命令,所以我们需要安装 subversion 和 cmake 两个软件。LLVM 也支持 Git 了,但是好像不是所有的子项目都支持,所以这里没做研究。
sudo apt install subversion
sudo apt install cmake
下载 LLVM 核心代码
Checkout LLVM from Subversion
首先我们建立一个文件夹 llvm-source 用来存放源代码。由于同学使用的是 RELEASE_500 这一版本,所以这里我也下载这一版本 LLVM 核心代码仓库。
mkdir llvm-source-build
cd llvm-source-build
svn co http://llvm.org/svn/llvm-project/llvm/tags/RELEASE_500/final llvm
下载 Clang 源码
llvm-project,切到 llvm 核心代码的 tools 目录下,下载 Clang 的源码。下载完成后,返回到 llvm 目录下。
cd llvm/tools
svn co http://llvm.org/svn/llvm-project/cfe/tags/RELEASE_500/final clang
cd ..
下载 Clang 工具源码
切换到 clang 目录下,下载 clang 工具源码。这一步是可选的。下载完成后返回到 llvm 目录下。
cd tools/clang/tools
svn co http://llvm.org/svn/llvm-project/clang-tools-extra/tags/RELEASE_500/final extra
cd ../../..
下载Compiler-RT 源码
cd projects
svn co http://llvm.org/svn/llvm-project/compiler-rt/tags/RELEASE_500/final compiler-rt
cd ..
下载标准库libcxx 和 libcxxabi
cd projects
svn co http://llvm.org/svn/llvm-project/libcxx/tags/RELEASE_500/final libcxx
svn co http://llvm.org/svn/llvm-project/libcxxabi/tags/RELEASE_500/final libcxxabi
cd ..
编译安装
首先返回到 llvm-source-build 目录下,新建 bulid 目录。切换到 build 目录下。使用 cmake 得到 Makefile文件,之后使用 make 编译,由于我是安装在 12 核心的服务器上,稍微查了一下文档,LLVM 支持并行编译。所以我使用了 -j 参数指定了 12 个核心进行并行编译。接着使用 make install 安装即可。
-G “Unix Makefiles” 表示要使用 cmake 工具得到 Unix 环境的 Makefile。其他参数不一一介绍了,当然也安装过程也支持更多的参数,具体的参数可以参考## Options and variables。
cd ..
mkdir bulid
cd build
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" ../llvm
make -j 12
sudo make install
作者:衣介书生
链接:https://www.jianshu.com/p/861c1a630059
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
特别注意:使用svn命令有时候会出现错误,尤其是安装llcm和clang,很有可能会突然报错,说mismatch,可以删掉test再重新安一次,我就是这样试了好几次成功的!操作步骤:
cd llvm
svn cleanup
cd ..
svn co 重新执行
使用clang工具进行编译得到.ll文件
llvm有一个自己独有的IR码,又称之为llvm bitcode,它有三种存在形式:
clang编译的几个常用命令:针对c使用clang,针对cpp使用clang++
# 加载通文件,替换宏定义
clang -E test.cpp -o test.i
# .i文件由编译器处理得到汇编语言
clang -S test.i -o test.s
# 汇编文件重定向为目标程序
clang -c test.s -o test.o
#得到可执行程序
clang test.o -o test
# 也可一步到位 直接可执行程序
clang test.c -o test
#运行可执行程序
./test
# 重点来了!!编译得到ll文件
clang -o3 -emit-llvm test.c -c -o test.bc
clang -o3 -emit-llvm test.c -S -o test.ll
clang++ -o3 -emit-llvm test.cpp -S -o test.ll -std=c++11
如何使用llvm得到cfg有一篇大名鼎鼎的文章:eli
他提供的案例代码:github
遗憾的是这个代码似乎不太适用于我的ll文件,或者是因为我们使用的llvm版本不一致,得不到想要的输出,我做了一些修改。
一个文件中包含了很多个函数,获取每个函数的名称,函数中BB块的类型,BB块中每条指令的操作指令,指令中使用值的ID,因为函数中可能包含回路环,所以使用了强连通分量的遍历方式,下面是关键代码示例:
for (std::vector::const_iterator BBI = nextSCC.begin(), BBIE = nextSCC.end(); BBI != BBIE; ++BBI) {
Type *type = (*BBI)->getType();
outs() <<"[BB-Type]: B"<getTypeID() <<"\n";
BasicBlock *BB = (*BBI);
for(Instruction &I : *BB){
outs() << "[BB-Instruction]: I" << I.getOpcode() <<",Info:"<< I <<"\n";
for(Use &U :I.operands()){
Value *v = U.get();
outs() << "[Value-ID]: V" << v->getValueID() <<"\n";
}
}
if (nextSCC.size() == 1 && SCCI.hasLoop())
errs() << " (Has self-loop).";
}
llvm的API可以在这里查询:添加链接描述
编译方式:
clang++ -o3 -c $(llvm-config --cxxflags) main.cpp -o main.o
clang++ main.o $(llvm-config --ldflags --libs) -lpthread
./a.out -scc test.ll