llvm学习(一):简介与安装

最近在搞llvm,最终目的是做 Android 上 Native 的加固,感谢椒哥(小花椒)的帮助,开个系列记录和分享一下吧。

一、llvm 和 clang 简介

llvm 是个框架,clang 是处理与 C 相关的工具,可以认为是 gcc。(我乱解释的,不一定对)。因为 llvm 的可拓展性好,可以在编译过程中执行一些操作,让编译出来的可执行文件自带混淆,也就实现了我们预期的功能。

二、手动编译安装

(之后的文章均以这个环境为基准,不要问我brew install的为什么会加载Pass出现符号NotFound)

2018年9月,llvm 更了个大版本,到了llvm7.0,上次有印象还是 llvm4.0 的时代,以前从来没摸过这个东西,感觉还是很有意思的。

【如果是 debug 版,准备50G 左右的空间。】

【如果是release版,只需要10G以内的空间。具体请阅读本系列的第九篇。】

下载两个东西,下载地址 ==>http://releases.llvm.org/download.html#7.0.0

llvm-7.0.0.src.tar.xzcfe-7.0.0.src.tar.xz ,前者是llvm,后者是clang等工具,执行下面的命令,解压并且移动过去。

1
2
3
4
5
xz -d llvm-7.0.0.src.tar.xz
tar xvf llvm-7.0.0.src.tar
xz -d cfe-7.0.0.src.tar.xz
tar xvf cfe-7.0.0.src.tar
mv cfe-7.0.0.src ./llvm-7.0.0.src/tools <-最好重命名为clang,否则在编译其他组件(例如lldb依赖clang)时,会出现符号找不到的错误

然后按照官方的说明进行操作即可,可以跳过下面这部分。

这里我使用 b 目录存放build 过程的文件,使用 i 目录存放将来 install 的文件。

【注意:使用下方命令编译出来的是 debug 版,大部分情况下使用 release 版就够了】

b
1
2
3
4
cd b
## This is debug build
cmake ../llvm-7.0.0.src
cmake --build . -- -j 8

等待几十分钟后,会在 b 目录里生成很多有用的文件。 建议使用 Release 版而且带有assert 功能,我平时这样是够用的。

1
➜ pllvm cmake ../llvm-7.0.0.src -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON

因为我不认识里面的东西,所以我使用 install 安装了,安装到 i 文件夹里,命令如下。

1
2
3
mkdir i
export LLVM_HOME=$PWD/i
cmake -DCMAKE_INSTALL_PREFIX=$LLVM_HOME -P cmake_install.cmake

这里建议定义LLVM_HOME这个环境变量,方便操作,也方便后面的操作。 安装好大概是这样的:

1
2
3
4
5
6
7
8
9
-> i lsa
total 0
drwxr-xr-x 7 leadroyal staff 224B Oct 9 16:32 .
drwxr-xr-x 6 leadroyal staff 192B Oct 10 13:28 ..
drwxr-xr-x 77 leadroyal staff 2.4K Oct 9 16:33 bin
drwxr-xr-x 6 leadroyal staff 192B Oct 9 16:32 include
drwxr-xr-x 173 leadroyal staff 5.4K Oct 9 16:33 lib
drwxr-xr-x 4 leadroyal staff 128B Oct 9 16:32 libexec
drwxr-xr-x 7 leadroyal staff 224B Oct 9 16:33 share

建议在 PATH里也添加 $LLVM_HOME/bin,因为 Mac 上默认的 LLVM 是/usr/bin/clang,版本太老了而且无法更新,会影响到后面 Pass 的开发。

三、验证

1
2
3
4
5
6
7
8
9
10
➜  /tmp $LLVM_HOME/bin/clang --version
clang version 7.0.0 (tags/RELEASE_700/final)
Target: x86_64-apple-darwin18.0.0
Thread model: posix
InstalledDir: /Users/leadroyal/pllvm/I/bin

➜ /tmp $LLVM_HOME/bin/clang -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include /tmp/test.c

➜ /tmp ./a.out
hello world

emmmmm 可以正常使用,吼啦,将来我们就用它! 【又水了一篇 blog,23333】