【LLVM】Getting Started with the LLVM System(Part 1)

概述

欢迎来到LLVM项目!
LLVM项目有多个组件。该项目的核心本身被称为“LLVM”。它包含处理中间表示(Intermediate Representations,IR)并将其转换为对象文件所需的所有工具、库和头文件。工具包括汇编程序、反汇编程序、位代码分析器和位代码优化器。它还包含基本的回归测试。
还有一个重要的组件是Clang前端。这个组件将C、C++、Objective C和Objective C++代码编译成LLVM bitcode,并使用LLVM将其转换成目标文件。
LLVM中还有其他组件,包括libc ++ C ++标准库LLD链接器等。


LLVM源码下载及构建

LLVM入门文档可能已过期。 因此,我们可以通过Clang入门文档来学习LLVM。
我们可以通过以下步骤获取和配置LLVM:

  1. 获取LLVM源码(包换相关子程序,如Clang)
 $ git clone https://github.com/llvm/llvm-project.git

windows平台的源码获取方式为:

 $ git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git

为了节省存储空间和加快代码获取时间,您可能需要进行浅层克隆。例如,如果想到获取最近版本的LLVM,可以使用以下命令:

 $ git clone --depth 1 https://github.com/llvm/llvm-project.git
  1. 配置及构建LLVM和Clang
 $ cd llvm-project
 $ mkdir build
 $ cd build
 $ cmake -G <generator> [options] ../llvm

一些常用的生成器(generator):

  • Ninja - 用于生成Ninja构建文件。大多数llvm开发人员使用Ninja。
  • Unix Makefiles - 用于生成与make兼容的并行makefiles。
  • Visual Studio - 用于生成Visual Studio项目和解决方案。
  • Xcode - 用于生成Xcode项目。

一些常用的选项(options):

  • -DLLVM_ENABLE_PROJECTS=’…’ - 子项目列表,当构建子项目时,子项目之间用分号来分隔。可以包括以下任何一个:clang,clang-tools-extra,libcxx,libcxxabi,libunwind,lldb,compiler-rt,lld,polly或debuginfo-tests。例如,要构建LLVM,Clang,libcxx和libcxxabi,请使用-DLLVM_ENABLE_PROJECTS =“clang; libcxx; libcxxabi”。
  • -DCMAKE_INSTALL_PREFIX=directory - 指定要安装LLVM工具和库的完整路径名(默认为 /usr/local)
  • -DCMAKE_BUILD_TYPE=type - type的有效选项是Debug,Release,RelWithDebInfo和MinSizeRel。默认为Debug。
  • -DLLVM_ENABLE_ASSERTIONS=On - 编译时启用断言(对于Debug构建,默认为Yes,对于所有其他构建类型,默认为No)。

用cmake --build . [–target ]命令或上述指定的构建系统编译。

  • 当target为默认值(即 cmake --build . 或 make)将构建所有LLVM。
  • 当target为check-all(即ninja check-all)将运行回归测试以确保一切正常。
  • CMake将为每个工具和库生成构建target,大多数LLVM子项目都会生成自己的check- target。
  • 用串行构建会很慢。要提高速度,请尝试运行并行构建。Ninja是默认并行,对于make,使用选项-j NN,其中NN是并行作业的数量,例如可用CPU的数量。

更多信息,请参阅CMake
如果出现“内部编译器错误(ICE)”或测试失败,请参阅下文。


环境要求

在开始使用LLVM之前,请查看下面列出的环境要求。提前知道你需要什么硬件和软件,这可能会帮你省去一些麻烦。

硬件

LLVM可在以下主机平台上工作:
在这里插入图片描述
注意:

  1. 仅奔腾处理器及更高版本支持代码生成
  2. 仅32位ABI支持代码生成
  3. 要在基于Win32的系统上使用LLVM模块,可以使用-DBUILD_SHARED_LIBS=on配置LLVM。

调试构建需要大量时间和磁盘空间。仅限LLVM的构建将需要大约1-3 GB的空间。LLVM和Clang的完整构建将需要大约15-20GB的磁盘空间。具体的空间要求将因系统而异。(由于所有调试信息以及库静态链接到多个工具中,所以需要很多空间)。
如果空间受限,则只能选构建一部分工具和目标。Release版本需要的空间要少得多。
理论上LLVM大件可以在其他平台上编译,但是不能保证能编译成功。如果编译成功,LLVM实用程序应该能够汇编、反汇编、分析和优化LLVM bitcode。代码生成也应该是有效的,尽管生成的本机代码可能无法在你的平台工作。

软件

编译LLVM需要安装多个软件包。下表列出了所需的软件包。Package列是LLVM所依赖的软件包的常用名称。“Version”列提供包的“已知可用”版本。Notes列描述了LLVM如何使用该包,并提供了其他详细信息。
在这里插入图片描述
注意:

  1. 只需要C和C++,所以不需要为LLVM构建其他语言。具体版本信息见下文。
  2. 仅当您希望在llvm/test目录中运行自动测试套件时才需要。
  3. 可选,向选定的LLVM工具添加压缩/解压缩功能。
  4. 可选,您可以使用CMake支持的任何其他构建工具。

另外,编译主机通常会有大量的Unix实用程序。如下:

  • ar — 归档库构建器
  • bzip2 — bzip2文件压缩命令
  • bunzip2 — bzip2文件解压缩命令
  • chmod — 修改文件权限
  • cat — 连接文件并打印到标准输出设备上
  • cp — 拷贝文件
  • date — 打印当前日期/时间
  • echo — 打印到标准输出
  • egrep — 扩展正则表达式搜索实用程序
  • find — 查找文件/目录
  • grep — 正则表达式搜索实用程序
  • gzip — gzip文件压缩命令
  • gunzip — gzip文件解压缩命令
  • install — 安装目录/文件
  • mkdir — 创建目录
  • mv — 移动(重命名)文件
  • ranlib — 归档符号表构建器
  • rm — 删除文件和目录
  • sed — 用于转换输出的SED流编辑器
  • sh — 用于生成构建脚本的bourne shell
  • tar — 打包命令
  • test — 在文件系统中测试东西
  • unzip — zip文件解压命令
  • zip — zip文件压缩命令

C++主机工具链,编译器和标准库

LLVM对主机C++编译器非常苛刻,因此会暴露编译器中的错误。我们还试图紧跟C++的改进和发展。因此,我们需要一个C++现代主机工具链,编译器和标准库,以便建立LLVM。
LLVM是使用编码标准中的C++子集编写的。为了实施这种语言版本,我们检查最流行的主机工具链,以了解构建系统中的特定最低版本:

  • Clang 3.5
  • Apple Clang 6.0
  • GCC 5.1
  • Visual Studio 2019

这些工具链路的旧版本也可以工作,但需要使用一个特殊选项强制构建系统,而不是一个真正受支持的主机平台。还要注意的是,这些编译器的旧版本经常会崩溃或导致LLVM编译错误。
对于非主流的主机工具链,如ICC或XLC,请注意,需要使用最新的版本来支持LLVM中使用的所有C++特性。
我们已知一部分作为主机工具链路使用会失败的软件版本。包括一些链接器。
gnu ld 2.16.x. 当“.gnu.linkonce.t.*”在废弃部分定义时,一些2.16.x版本的ld链接器将产生非常长的警告消息。这些告警消息是可以忽略的,并且链接是正确的。这些信息可以使用LD 2.17屏蔽。
gnu-binutils 2.17:binutils 2.17包含一个bug,它在构建llvm时会耗费很多时间来链接(分钟而不是秒)。我们建议升级到较新版本(2.17.50.0.4或更高版本)。
gnu-binutils 2.19.1gold:这个版本的gold包含一个bug,它在使用位置无关代码构建LLVM时会导致间歇性故障。我们建议升级到较新版本的gold。

获取现代主机C++工具链

本节主要适用于Linux和较旧的BSD。在macOS上使用的Xcode已经能满足要求,最多可能需要升级。Windows没有“系统编译器”,因此必须安装Visual Studio 2019(或更高版本)或最新版本的mingw64。FreeBSD 10.0及更新版本的系统编译器采用了现代的Clang。
然而,一些版本的Linux和一些其他或更老的BSD有时使用的是非常老的GCC版本。这些步骤试图帮助您在这样的系统上升级编译器。但是,最好还是用最新版并符合这些要求的编译器。请注意,安装Clang和libc++的早期版本作为主机编译器是很有诱惑力的,但是直到最近,libc++还没有经过良好的测试或设置,无法在Linux上构建。因此,本指南建议只使用libstdc++和现代GCC作为初始主机,然后使用Clang(可能还有libc++)。
第一步是安装最新的GCC工具链。用户最常见的版本要求是UbuntuPrecise,12.04LTS。对于这个版本,最简单的方法是安装工具链测试PPA,并使用它安装现代GCC。在ask ubuntu stack exchangegithub gist上有一个非常好的讨论,其中包含更新的命令。然而,并非所有用户都可以使用PPA,而且还有许多其版本,所以从源代码构建和安装GCC可能是必要的(或者只是有用的,如果您在这里进行编译器开发的话)。现在也很容易做到。
安装GCC 5.1.0的简单步骤:

% gcc_version=5.1.0
% wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2
% wget https://ftp.gnu.org/gnu/gcc/gcc-${gcc_version}/gcc-${gcc_version}.tar.bz2.sig
% wget https://ftp.gnu.org/gnu/gnu-keyring.gpg
% signature_invalid=`gpg --verify --no-default-keyring --keyring ./gnu-keyring.gpg gcc-${gcc_version}.tar.bz2.sig`
% if [ $signature_invalid ]; then echo "Invalid signature" ; exit 1 ; fi
% tar -xvjf gcc-${gcc_version}.tar.bz2
% cd gcc-${gcc_version}
% ./contrib/download_prerequisites
% cd ..
% mkdir gcc-${gcc_version}-build
% cd gcc-${gcc_version}-build
% $PWD/../gcc-${gcc_version}/configure --prefix=$HOME/toolchains --enable-languages=c,c++
% make -j$(nproc)
% make install

有关更多详细信息,请查看GCC wiki,我从中获得了大部分信息。
一旦拥有了GCC工具链,就可以配置LLVM的构建,以便主机编译器和C++标准库使用新的工具链。因为libstdc++的新版本不在系统库搜索路径上,所以需要传递额外的链接器标志,以便在链接时(-l)和运行时(-rpath)找到它。如果您正在使用cmake,则此调用将生成工作的二进制文件:

% mkdir build
% cd build
% CC=$HOME/toolchains/bin/gcc CXX=$HOME/toolchains/bin/g++ \
  cmake .. -DCMAKE_CXX_LINK_FLAGS="-Wl,-rpath,$HOME/toolchains/lib64 -L$HOME/toolchains/lib64"

如果设置rpath失败,大多数llvm二进制文件在启动时都会失败,在加载类似libstdc++.so.6程序会报错:version `GLIBCXX_3.4.20’ not found。这意味着您需要调整-rpath链接器标志。
当您构建Clang时,您需要让它访问现代C++标准库,以便在引导程序中使用它作为您的新主机。有两种简单的方法可以做到这一点,要么构建(安装)libc++和clang,然后将其与-stdlib=libc++编译和链接标志一起使用,要么将clang安装到与gcc相同的前缀($home/toolchains)。clang将在自己的前缀中查找libstdc++并在使用它。您还可以为clang添加一个显式前缀,以便使用–gcc toolchain=/opt/my/gcc/prefix标志查找gcc工具链,在使用刚刚构建的clang引导时将其传递给编译和链接命令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值