LLVM 系统入门¶
Posted rtoax
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LLVM 系统入门¶相关的知识,希望对你有一定的参考价值。
Getting Started with the LLVM System — LLVM 15.0.0git documentationhttps://llvm.org/docs/GettingStarted.html
目录
概述
欢迎来到 LLVM 项目!
LLVM 项目有多个组件。该项目的核心本身称为“LLVM”。这包含处理中间表示并将其转换为目标文件所需的所有工具、库和头文件。工具包括汇编器、反汇编器、位码分析器和位码优化器。它还包含基本的回归测试。
类 C 语言使用Clang前端。该组件使用 LLVM 将 C、C++、Objective C 和 Objective C++ 代码编译为 LLVM 位码,并从那里编译为目标文件。
其他组件包括:libc++ C++ 标准库、LLD 链接器等。
获取源代码并构建 LLVM
LLVM 入门文档可能已过期。Clang 入门页面可能包含更准确的信息。
这是获取和构建 LLVM 源的示例工作流和配置:
-
Checkout LLVM(包括 Clang 等相关子项目):
git clone https://github.com/llvm/llvm-project.git
- 或者,在窗户上,
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
-
配置和构建 LLVM 和 Clang:
-
cd llvm-project
-
mkdir build
-
cd build
-
cmake -G <generator> [options] ../llvm
一些常见的构建系统生成器是:
Ninja
— 用于生成Ninja 构建文件。大多数 llvm 开发人员使用 Ninja。Unix Makefiles
— 用于生成与 make 兼容的并行 makefile。Visual Studio
— 用于生成 Visual Studio 项目和解决方案。Xcode
— 用于生成 Xcode 项目。
一些常见的选项:
-
-DLLVM_ENABLE_PROJECTS='...'
— 您要另外构建的 LLVM 子项目的分号分隔列表。可以包括以下任何一种:clang、clang-tools-extra、lldb、compiler-rt、lld、polly 或跨项目测试。例如,要构建 LLVM、Clang、libcxx 和 libcxxabi,请使用 .
-DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi"
-
-DCMAKE_INSTALL_PREFIX=directory
— 为目录指定要安装 LLVM 工具和库的位置的完整路径名(默认/usr/local
)。 -
-DCMAKE_BUILD_TYPE=type
—类型的有效选项是 Debug、Release、RelWithDebInfo 和 MinSizeRel。默认为调试。 -
-DLLVM_ENABLE_ASSERTIONS=On
— 在启用断言检查的情况下编译(Debug 构建默认为 Yes,所有其他构建类型默认为 No)。
-
cmake --build . [--target <target>]
或上面直接指定的构建系统。- 默认目标(即或)将构建所有 LLVM。
cmake --build .
make
check-all
目标(即)将运行回归测试以确保一切正常。ninja check-all
- CMake 将为每个工具和库生成构建目标,并且大多数 LLVM 子项目都会生成自己的
check-<project>
目标。 - 运行串行构建会很慢。要提高速度,请尝试运行并行构建。这是 Ninja 默认完成的;对于
make
,使用选项,其中是并行作业的数量,例如可用 CPU 的数量。-j NN
NN
- 默认目标(即或)将构建所有 LLVM。
-
有关更多信息,请参阅CMake
-
如果您收到“内部编译器错误 (ICE)”或测试失败,请参见 下文。
-
有关配置和编译 LLVM 的详细信息,请参阅LLVM 入门部分。转到目录布局以了解源代码树的布局。
要求
在开始使用 LLVM 系统之前,请查看下面给出的要求。通过提前了解您将需要哪些硬件和软件,这可能会为您节省一些麻烦。
硬件
众所周知,LLVM 可在以下主机平台上工作:
操作系统 | 拱 | 编译器 |
---|---|---|
Linux | x86 1 | 海合会,铿锵 |
Linux | amd64 | 海合会,铿锵 |
Linux | 手臂 | 海合会,铿锵 |
Linux | 米普斯 | 海合会,铿锵 |
Linux | 电源PC | 海合会,铿锵 |
Linux | SystemZ | 海合会,铿锵 |
索拉里斯 | V9 (Ultraparc) | 海合会 |
蜻蜓BSD | amd64 | 海合会,铿锵 |
自由BSD | x86 1 | 海合会,铿锵 |
自由BSD | amd64 | 海合会,铿锵 |
NetBSD | x86 1 | 海合会,铿锵 |
NetBSD | amd64 | 海合会,铿锵 |
OpenBSD | x86 1 | 海合会,铿锵 |
OpenBSD | amd64 | 海合会,铿锵 |
macOS 2 | 电源PC | 海合会 |
苹果系统 | x86 | 海合会,铿锵 |
赛格温/Win32 | x86 1、3 | 海合会 |
视窗 | x86 1 | 视觉工作室 |
视窗 x64 | x86-64 | 视觉工作室 |
笔记
- Pentium 处理器及更高版本支持代码生成
- 仅支持 32 位 ABI 的代码生成
- 要在基于 Win32 的系统上使用 LLVM 模块,您可以使用
-DBUILD_SHARED_LIBS=On
.
请注意,调试版本需要大量时间和磁盘空间。仅 LLVM 构建将需要大约 1-3 GB 的空间。LLVM 和 Clang 的完整构建将需要大约 15-20 GB 的磁盘空间。确切的空间要求因系统而异。(由于所有的调试信息以及库静态链接到多个工具的事实,它是如此之大)。
如果空间有限,您可以只构建选定的工具或只构建选定的目标。发布版本需要的空间要少得多。
LLVM 套件可以在其他平台上编译,但不能保证这样做。如果编译成功,LLVM 实用程序应该能够组装、反汇编、分析和优化 LLVM 位码。代码生成也应该可以工作,尽管生成的本机代码可能无法在您的平台上工作。
软件
编译 LLVM 需要您安装多个软件包。下表列出了这些必需的软件包。Package 列是 LLVM 所依赖的软件包的常用名称。版本列提供包的“已知工作”版本。Notes 列描述了 LLVM 如何使用该包并提供其他详细信息。
包裹 | 版本 | 笔记 |
---|---|---|
制作 | >=3.13.4 | Makefile/工作区生成器 |
海合会 | >=7.1.0 | C/C++ 编译器1 |
Python | >=3.6 | 自动化测试套件2 |
zlib | >=1.2.3.4 | 压缩库3 |
GNU 制作 | 3.79, 3.79.1 | 生成文件/构建处理器4 |
笔记
- 只需要 C 和 C++ 语言,因此无需为 LLVM 的目的构建其他语言。具体版本信息见下文。
- 仅当您想在
llvm/test
目录中运行自动化测试套件时才需要。 - 可选,为选定的 LLVM 工具添加压缩/解压缩功能。
- 可选,您可以使用 CMake 支持的任何其他构建工具。
此外,您的编译主机应具有通常过多的 Unix 实用程序。具体来说:
- ar — 档案库构建器
- bzip2 — 用于分发生成的 bzip2 命令
- bunzip2 — 用于分发检查的 bunzip2 命令
- chmod — 更改文件的权限
- cat — 输出连接实用程序
- cp — 复制文件
- date — 打印当前日期/时间
- echo — 打印到标准输出
- egrep — 扩展的正则表达式搜索工具
- find — 在文件系统中查找文件/目录
- grep — 正则表达式搜索工具
- gzip — 用于分发生成的 gzip 命令
- gunzip — 用于分发检查的 gunzip 命令
- install — 安装目录/文件
- mkdir — 创建一个目录
- mv — 移动(重命名)文件
- ranlib — 归档库的符号表构建器
- rm — 删除(删除)文件和目录
- sed — 用于转换输出的流编辑器
- sh — 用于构建脚本的 Bourne shell
- tar — 用于分发生成的磁带存档
- test — 测试文件系统中的东西
- unzip — 用于分发检查的解压缩命令
- zip — 用于分发生成的 zip 命令
宿主 C++ 工具链,编译器和标准库
LLVM 对宿主 C++ 编译器的要求非常高,因此往往会暴露编译器中的错误。我们还试图合理地密切关注 C++ 语言和库的改进和发展。因此,我们需要一个现代主机 C++ 工具链,包括编译器和标准库,以构建 LLVM。
LLVM 是使用编码标准中记录的 C++ 子集编写的。为了强制执行此语言版本,我们在我们的构建系统中检查最流行的主机工具链以获取特定的最低版本:
- 铿锵声 5.0
- 苹果叮当 9.3
- 海合会 7.1
- 视觉工作室 2019 16.7
任何比这些工具链更早的东西都可以工作,但需要使用特殊选项强制构建系统,并且不是真正受支持的主机平台。另请注意,这些编译器的旧版本经常崩溃或错误编译 LLVM。
对于不太广泛使用的主机工具链,例如 ICC 或 xlC,请注意,可能需要最新版本来支持 LLVM 中使用的所有 C++ 功能。
我们跟踪某些版本的软件,这些版本在用作主机工具链的一部分时会出现故障。这些甚至有时包括链接器。
GNU ld 2.16.X。一些 2.16.X 版本的 ld 链接器会产生很长的警告消息,抱怨.gnu.linkonce.t.*
在丢弃的部分中定义了一些“ ”符号。您可以放心地忽略这些消息,因为它们是错误的并且链接是正确的。这些消息使用 ld 2.17 消失。
GNU binutils 2.17:Binutils 2.17 包含一个错误,该错误会在构建 LLVM 时导致巨大的链接时间(几分钟而不是几秒)。我们建议升级到更新版本(2.17.50.0.4 或更高版本)。
GNU Binutils 2.19.1 Gold:此版本的 Gold 包含一个错误,该错误会在使用位置无关代码构建 LLVM 时导致间歇性失败。症状是关于循环依赖的错误。我们建议升级到新版本的 Gold。
本节主要适用于 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 工具链。用户遇到版本要求的最常见发行版是 Ubuntu Precise,12.04 LTS。对于这个发行版,一个简单的选择是安装工具链测试 PPA并使用它来安装现代 GCC。在ask ubuntu stack exchange和 带有更新命令的github gist上有一个非常好的讨论。但是,并非所有用户都可以使用 PPA,并且还有许多其他发行版,因此从源代码构建和安装 GCC可能是必要的(或者只是有用的,如果您在这里进行编译器开发)。这些天也很容易做到。
安装 GCC 7.1.0 的简单步骤:
% gcc_version=7.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 二进制文件将在启动时失败,并且来自加载程序的消息类似于. 这意味着您需要调整 -rpath 链接器标志。libstdc++.so.6: version `GLIBCXX_3.4.20' not found
此方法将为所有可执行文件的 rpath 添加绝对路径。这对当地的发展很好。如果您想分发您构建的二进制文件以便它们可以在旧系统上运行,请复制libstdc++.so.6
到该 lib/
目录中。所有 LLVM 的传送二进制文件都有一个指向 的 rpath $ORIGIN/../lib
,所以它们会在libstdc++.so.6
那里找到。非分布式二进制文件没有 rpath 集,也找不到libstdc++.so.6
. 传递 -DLLVM_LOCAL_RPATH="$HOME/toolchains/lib64"
给 cmake 以添加绝对路径,libstdc++.so.6
如上所述。由于这些二进制文件不是分布式的,因此拥有绝对本地路径对它们来说很好。
当您构建 Clang 时,您需要授予它对现代 C++ 标准库的访问权限,以便在引导程序中将其用作您的新主机。有两种简单的方法可以做到这一点,或者与 Clang 一起构建(和安装)libc++,然后将其与-stdlib=libc++
编译和链接标志一起使用,或者将 Clang 安装到与$HOME/toolchains
GCC 相同的前缀(如上)中。Clang 将在其自己的 libstdc++ 前缀中查找并在找到时使用它。您还可以为 Clang 添加显式前缀以查找带有--gcc-toolchain=/opt/my/gcc/prefix
标志的 GCC 工具链,在使用刚刚构建的 Clang 进行引导时将其传递给编译和链接命令。
LLVM 入门
本指南的其余部分旨在帮助您开始使用 LLVM,并为您提供有关 LLVM 环境的一些基本信息。
本指南的后面部分描述了LLVM 源代码树的一般布局,一个使用 LLVM 工具链的简单示例,以及用于查找有关 LLVM 的更多信息或通过电子邮件获得帮助的链接。
术语和符号
在本手册中,以下名称用于表示特定于本地系统和工作环境的路径。 这些不是您需要设置的环境变量,而只是下面本文档其余部分中使用的字符串。在下面的任何示例中,只需将这些名称中的每一个替换为本地系统上的适当路径名即可。所有这些路径都是绝对的:
SRC_ROOT
这是 LLVM 源代码树的顶级目录。
OBJ_ROOT
这是 LLVM 对象树的顶层目录(即放置对象文件和编译程序的树。它可以与 SRC_ROOT 相同)。
解压 LLVM 档案
如果您有 LLVM 发行版,则需要先将其解压缩,然后才能开始编译。LLVM 作为许多不同的子项目分发。每个都有自己的下载,这是一个用 gzip 程序压缩的 TAR 存档。
文件如下,xy标记版本号:
llvm-x.y.tar.gz
LLVM 库和工具的源代码发布。
cfe-x.y.tar.gz
Clang 前端的源代码发布。
从 Git 签出 LLVM
您还可以从 Git 签出 LLVM 的源代码。
笔记
在我们正确调整.gitattribute设置后,以后应该不需要通过,但在撰写本文时 Windows 用户需要。--config core.autocrlf=false
只需运行:
% git clone https://github.com/llvm/llvm-project.git
或在 Windows 上,
% git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git
这将在当前目录中创建一个 ' llvm-project
' 目录,并用 LLVM 和所有相关子项目的所有源代码、测试目录和文档文件的本地副本完全填充它。请注意,与将每个子项目包含在单独文件中的 tarball 不同,git 存储库包含所有项目。
如果您想获得特定版本(而不是最新版本),您可以在克隆存储库后签出标签。例如,在上述命令创建的目录中git checkout llvmorg-6.0.1 。llvm-project
使用git tag -l列出所有这些。
请也阅读开发者政策。
我们目前不接受 github 拉取请求,因此您需要通过电子邮件向 llvm-commits 发送补丁,或者最好通过Phabricator发送补丁。
您通常希望确保您的分支有一个提交,对应于您希望发送的评论,与上游 origin/main
分支保持同步,并且不包含合并。一旦你有了它,你就可以开始一个 Phabricator 审查(或使用或 输出差异,并将其附加到电子邮件中)。git show
git format-patch
但是,使用“Arcanist”工具通常更容易。安装 arcanist后,您还需要对您的 arcanist 存储库应用修复以提交补丁:
% cd arcanist
% git fetch https://github.com/rashkov/arcanist update_cacerts
% git cherry-pick e3659d43d8911e91739f3b0c5935598bceb859aa
完成后,您可以使用以下命令上传最新提交:
% arc diff HEAD~1
此外,在发送补丁以供审核之前,还请尝试确保其格式正确。我们为此使用clang-format
它,它通过git-clang-format
脚本集成了 git。在某些系统上,它可能已经安装(或者可以通过您的包管理器安装)。如果是这样,您可以简单地运行它——以下命令将仅格式化最近提交中更改的代码:
% git clang-format HEAD~1
请注意,这会修改文件,但不会提交它们——您可能想要运行
% git commit --amend -a
为了使用所有待处理的更改更新最后一次提交。
笔记
如果您的系统上尚未安装clang-format
或安装,二进制文件将与 clang 一起构建,并且 git 集成可以从 .git clang-format
clang-format
clang/tools/clang-format/git-clang-format
审查补丁后,您应该对其进行变基,在本地重新测试,并将更改提交到 LLVM 的主分支。如果您具有所需的访问权限,则可以使用git push完成此操作。请参阅为基于 Phabricator 的提交提交 更改或为提交访问获取 提交访问。
这是使用 git 的示例工作流。此工作流程假定您在名为branch-with-change的分支上已接受提交。
# Go to the branch with your accepted commit.
% git checkout branch-with-change
# Rebase your change onto the latest commits on Github.
% git pull --rebase origin main
# Rerun the appropriate tests if needed.
% ninja check-$whatever
# Check that the list of commits about to be pushed is correct.
% git log origin/main...HEAD --oneline
# Push to Github.
% git push origin HEAD:main
LLVM 当前有一个线性历史策略,这意味着不允许合并提交。github 上的llvm-project存储库被配置为拒绝包含合并的推送,因此需要上面的git rebase步骤。
如果您在使用特定的 git 工作流程时遇到问题,请寻求帮助。
我们包括一个可选的 pre-push 钩子,它对您将要推送的修订版运行一些健全性检查,并在您一次推送多个提交时询问确认。您可以通过从存储库根目录运行来设置它(在 Unix 系统上):
% ln -sf ../../llvm/utils/git/pre-push.py .git/hooks/pre-push
有关如何在 LLVM 上使用的信息,请参阅Klee 的限制(LLVM 程序分析工具)