安装 LLVM + Clang

LLVM 简介

LLVM 全称是 Low Level Virtual Machine,它是源自 the University of Illinois 的一个研究项目,该项目旨在提供一个现代化的编译机制,使得对任何编程语言既可以做到静态编译也可以动态编译,而且非常高效。后来 LLVM 项目逐渐发展,并孵化了许多子项目,比如 Clang,LLDB, OpenMP 等。

LLVM 核心库(core libraries)提供了一个源和目标相互独立的优化器,也即一个通用的编译优化和代码生成平台,还为对许多主流 CPU 提供了代码生成的支持。LLVM 定义了一个中间语言 LLVM IR,只要前端把代码编译成 LLVM IR,就可以使用 LLVM 丰富的优化模块和代码生成模块。换句话说,LLVM 让“创造一种计算机语言”变成了一个相对容易的事情,这件事情会有深远的影响。

Clang 作为 LLVM 原生的 " C/C++/Objective-C 编译器前端,是作为编译 C/C++ 代码的除 GCC 工具链之外的另一种选择。其有许多优点(比如像 LLVM 主页 所介绍的 Debug 模式下编译 Object C 速度比 GCC 快3倍,并且提供更加可读的编译过程中的出错信息等等),更多关于 Clang 的介绍可以去官网查看。

从代码上说,Clang 结构更简单。因为 Clang 只需要完成词法和语法分析,代码优化和机器代码的生成工作由 LLVM 完成。所以和全部由自己包下的 GCC 比起来,Clang 可以更专注地做好一件事。

而且,这种结构也使 Clang 可以被单独拿出来用在其他的程序里。比如 Vim 的 clang_complete 插件就是利用 Clang 进行语法分析后给出精确的自动补全和语法错误提示的。而 GCC 就没法很方便地做到这一点。

在实用性方面,除了有更快的编译速度更快和更友好的出错提示外,Clang 还内置有静态分析工具,可以对代码进行静态分析(clang --analyze)。这也是 GCC 做不到的。

另外,有关 Clang 和 GCC 的更多比较,还可以看知乎上这个帖子

简单来说,Clang 和 CompileRT 这两个子项目为 LLVM 提供了 C, C++, Objective C 和 Objective C++ 的前端及动态库支持,使得我们可以使用 Clang 来编译和构建项目。

由于 LLVM + Clang 项目得到了大财主 Apple 公司的大力赞助,最近这些年发展非常快,

本文介绍如何从源码编译安装 LLVM + Clang,截止本文所写日期最新版本是 Clang 3.9.1。

源码获取

要编译构建 Clang,必须先构建 LLVM 核心库。LLVM 核心库可以下载最新的发行包。也可以从远程库拉取代码。
Clang 源码 :http://llvm.org/releases/3.9.1/cfe-3.9.1.src.tar.xz
Compiler 源码 :http://llvm.org/releases/3.9.1/compiler-rt-3.9.1.src.tar.xz

最新的 LLVM 依赖 cmake 3.7.1,同时 还需要确保 libffi-3.2.1 和 Python-2.7.13 已经安装。

获取远程库代码

LLVM core, Clang 和 Compiler-RT 3个项目的源码是在独立的远程库中的,因此我们需要分别把这3个项目都拉取下来,同时还需要按照一定的组织结构放置。我们在本地创建一个 tmp 文件夹作为顶层目录来放置这3个项目的源码,llvm core 放在 tmp 目录下,而 clang 则放在 llvm 目录的 tools/下, complier-rt 放在 llvm 目录的 projects/ 下。

三个项目的源码拉取完成之后,组织结构应该如下所示:

llvm/
    /tools/clang
    /projects/compiler-rt

1.Checkout LLVM:

$ cd tmp
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm

2. Checkout Clang

$ cd llvm/tools
$ svn co http://llvm.org/svn/llvm-project/cfe/trunk clang

3. Checkout Compiler-RT(Optional)

$ cd llvm/projects
$ svn co http://llvm.org/svn/llvm-project/compiler-rt/trunk compiler-rt

编译及安装

LLVM 禁止源码内编译(in-tree build is not supported),因此我们需要在源码目录外新建一个单独的目录来存放编译后的文件,比如,在与 llvm 的同级的目录中新建一个 build 目录。然后进入该 build 目录进行编译。

需要先执行 cmake 命令生成 Makefile 或者 build.ninja 文件,这一步会检查编译所需的各项依赖(也即编译所需的环境要求),这里,我使用 Ninja 作为编译器并生成对应的 build.ninja,并指定 llvm 的安装目录为 /opt/llvm

$ cd build
$ cmake -G Ninja ../ \
  -DCMAKE_INSTALL_PREFIX=/opt/llvm  \
  -DCMAKE_BUILD_TYPE=Release \
  -DLLVM_ENABLE_FFI=ON \
  -DLLVM_BUILD_LLVM_DYLIB=ON \
  -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
  -DLLVM_TARGETS_TO_BUILD="host;AMDGPU" 
  -Wno-dev

如果本地已经安装 libffi 库,但依然提示找不到 libffi 库,
可以通过 -DFFI_INCLUDE_DIR=/usr/include-DFFI_LIBRARY_DIR=/usr/lib64 来手动指定。

NOTE: 编译时最好指定下面两个选项:

  • --enable-optimized 打开优化,默认情况下是关闭的。这样会生成大量 debug 信息,以致于产生的文件可能高达 9.4 G 之多,这可能很快耗尽磁盘空间导致编译失败。
  • --enable-targets=host-only 选择目标平台,默认情况下会生成所有平台的。这里设置成 host-only 只选择本机即可。

成功检测并生成 build.ninja 文件之后,直接执行 ninja 命令进行编译构建。
由于 LLVM + Clang 比较庞大,编译这一步会比较漫长,ninja 会默认使用系统所有 CPU 进行并发编译,这样的好处是编译速度非常快,但是会导致链接过程占用非常庞大的内存空间,因此如果系统的内存不够的话,最好不要使用所有的核来编译你,最好手动指定并发核数(比如执行 ninja -j4 来指定并发数为 4)。这样可以避免由于内存不够而导致的编译出错。

编译成功之后执行 ninja install 来完成安装。

所有安装的二进制程序包括:

bugpoint, c-index-test, clang, clang++ (symlinks to clang-<version>), clang-<version>, clang-check, clang-cl, clang-format, git-clang-format, llc, lli, llvm-ar, llvm-as, llvm-bcanalyzer, llvm-config, llvm-cov, llvm-c-test, llvm-cxxdump, llvm-diff, llvm-dis, llvm-dsymutil, llvm-dwarfdump, llvm-dwp, llvm-extract, llvm-lib (symlink to llvm-ar), llvm-link, llvm-lto, llvm-mc, llvm-mcmarkup, llvm-nm, llvm-objdump, llvm-pdbdump, llvm-profdata, llvm-ranlib (symlink to llvm-ar), llvm-readobj, llvm-rtdyld, llvm-size, llvm-split, llvm-stress, llvm-symbolizer, llvm-tblgen, obj2yaml, opt, sancov, sanstats, scan-build, scan-view, verify-uselistorder, and yaml2obj

安装的库文件包括:
BugpointPasses.so, LLVMHello.so, libLLVM.so, libLLVM.a (57 libraries), libLTO.so, libclang.so and libclang.a (24 libraries)

libc++ 介绍

libc++ 是由 Apple 公司为其 Mac OS X 平台专门开发的一个 C++ 标准库,其是针对 Clang 而开发完成的,包含了对 C++11 的完整支持,可以作为 Clang 的“御用” C++ 库。libc++ 作为另一个 C++ 标准的实现(传统的是 libstdc++),其与 Clang 的关系就像 libstdc++ 和 GCC 之间的关系一样。但是由于 Apple 公司向来喜欢走不兼容的路线,它在最新版的 Max OS X 中没有提供最新版的 libstdc++ 库(支持 C++11),如果需要使用 libstdc++ 库的话我们必须手动编译安装。

需要注意的是,按照上述流程安装完 LLVM + Clang 之后,默认是没有安装 libc++ 的,但 Clang 也可以用 libstdc++,所以执行 clang++ --std=c++11 main.cpp 就可以编译 C++11 的源码。

编译安装 libc++

1. Checkout libc++:

cd llvm/projects
svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx

2. Checkout libc++abi:

cd llvm/projects
svn co http://llvm.org/svn/llvm-project/libcxxabi/trunk libcxxabi

3. Configure and build libc++ with libc++abi:
注意: LLVM 只支持使用 CMake 来构建编译配置
推荐使用 Clang 来编译构建 libc++。

cd build
cmake -G  Makefile -DLLVM_PATH=path/to/llvm \
        -DLIBCXX_CXX_ABI=libcxxabi \
        -DLIBCXX_CXX_ABI_INCLUDE_PATHS=path/to/libcxxabi/include \
        path/to/libcxx

注意:如果本机已经有一个 libc++ 了,那么不要随意覆盖它,可能会导致由其编译而生成的库不再工作。可以使用 Cmake 的 CMAKE_INSTALL_PREFIX 选项去指定一个安全的安装位置。

配置完成之后,执行下列命令进行构建:

make cxx                                   — will build libc++ and libc++abi.
make check-cxx check-cxxabi                — will run the test suites.

编译完成之后执行下列命令安装

make install
下面是 LLVM + Clang 所安装的程序简介:

bugpoint      the automatic test case reduction tool.
clang       the Clang C, C++, and Objective-C compiler.
clang-format   a tool to format C/C++/Java/JavaScript/Objective-C/Protobuf code.
llc        the LLVM static compiler.
lli        used to directly execute programs from LLVM bitcode.
llvm-ar      the LLVM archiver.
llvm-as      the LLVM assembler.
llvm-bcanalyzer  the LLVM bitcode analyzer.
llvm-config    Prints LLVM compilation options.
llvm-cov     used to emit coverage information.
llvm-c-test    bytecode disassembler.
llvm-cxxdump   used as a C++ ABI Data Dumper.
llvm-diff     the LLVM structural 'diff'.
llvm-dis     the LLVM disassembler.
llvm-dsymutil   a tool used to manipulate archived DWARF debug symbol files,
          compatible with the Darwin command dsymutil.
llvm-dwarfdump   prints the content of DWARF sections in object files.
llvm-dwp      merges split DWARF files.
llvm-extract    used to extract a function from an LLVM module.
llvm-link      the LLVM linker.
llvm-lto      the LLVM LTO (link time optimization) linker.
llvm-mc      a standalone machine code assembler/disassembler.
llvm-nm      used to list LLVM bitcode and object file's symbol table.
llvm-objdump   an LLVM object file dumper.
llvm-pdbdump   used as PDB Dumper.
llvm-profdata   a small tool to manipulate and print profile data files.
llvm-ranlib    used to generate an index for a LLVM archive.
llvm-readobj   displays low-level format-specific information about object files.
llvm-rtdyld    the LLVM MC-JIT tool.
llvm-size     the LLVM object size dumper.
llvm-split     the LLVM module splitter.
llvm-stress    used to generate random .ll files.
llvm-symbolizer  converts adresses into source code locations.
llvm-tblgen    the LLVM Target Description To C++ Code Generator.
obj2yaml     takes an object file,and produces a YAML representation of it.
opt        the LLVM optimizer.
sancov      the sanitizer coverage processing tool.
sanstats     the sanitizer statistics processing tool.
scan-build    a Perl script that invokes the Clang static analyzer.
scan-view     a viewer for Clang static analyzer results.
verify-uselistorder the LLVM tool to verify use-list order.
yaml2obj     takes a YAML representation of an object file and converts it to an binary file.

参考

http://clang.llvm.org/get_started.html
https://libcxx.llvm.org/
http://libcxx.llvm.org/docs/BuildingLibcxx.html
https://github.com/maidsafe-archive/MaidSafe/wiki/Hacking-with-Clang-llvm-abi-and-llvm-libc

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容