Getting Started with the LLVM System

1.概述
欢迎来到LLVM项目! 为了开始,您首先需要了解一些基本信息。

首先,LLVM项目有多个组件。 该项目的核心本身称为“LLVM”。 它包含处理中间表示并将其转换为目标文件所需的所有工具,库和头文件。 它包含汇编器,反汇编器,bitcode分析器和bitcode优化器。 它还包含基本的回归测试。

另一件是Clang前端。 该组件将C,C ++,Objective C和Objective C ++代码编译为LLVM bitcode  - 并使用LLVM从那里编译成目标文件。

还有其他组件:libc ++ C ++标准库,LLD链接器等。

2.快速入门(摘要)
LLVM入门文档可能已过期。 因此,Clang入门页面也可能是一个很好的起点。

以下是使用LLVM快速启动和运行的简短故事:

  1. 阅读文档。
  2. 阅读文档。
  3. 请记住,您在阅读文档时被警告了两次。
  4. Checkout LLVM(包括像Clang这样的相关子项目):git clone https://github.com/llvm/llvm-project.git,Or, on windows, git clone --config core.autocrlf=false https://github.com/llvm/llvm-project.git
  5. 配置和构建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,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  - 类型的有效选项是Debug,Release,RelWithDebInfo和MinSizeRel。默认为Debug。
  • -DLLVM_ENABLE_ASSERTIONS = On  - 在启用断言检查的情况下编译(对于Debug构建,默认值为Yes,对于所有其他构建类型,默认值为No)。

运行您选择的构建工具!

  • 默认目标(即忍者或制作)将构建所有LLVM。
  • check-all目标(即ninja check-all)将运行回归测试以确保一切正常。
  • CMake将为每个工具和库生成构建目标,并且大多数LLVM子项目会生成自己的check- <project>目标。
  • 运行串行构建将很慢。 确保运行并行构建。 这在Ninja默认已经完成; 对于make,使用make -j NNN(具有适当的NNN值,例如你拥有的CPU数量。)

有关更多信息,请参阅CMake

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

3.要求
在开始使用LLVM系统之前,请查看下面给出的要求。 通过提前了解您需要的硬件和软件,这可以为您节省一些麻烦。

4.硬件
已知LLVM可在以下主机平台上运行:

 注意

请注意,Debug构建需要大量的时间和磁盘空间。 仅LLVM构建需要大约1-3 GB的空间。 完整版的LLVM和Clang将需要大约15-20 GB的磁盘空间。 确切的空间要求因系统而异。 (由于所有调试信息以及库静态链接到多个工具的事实,它是如此之大)。

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

如果空间受限,则只能构建选定的工具或仅构建选定的目标。 Release版本需要的空间要少得多。

LLVM套件可以在其他平台上编译,但不保证这样做。 如果编译成功,LLVM实用程序应该能够组装,反汇编,分析和优化LLVM bitcode。 代码生成也应该有效,尽管生成的本机代码可能无法在您的平台上运行。

5.软件
编译LLVM需要安装多个软件包。 下表列出了所需的包。 Package列是LLVM依赖的软件包的通常名称。 Version列提供了包的“已知工作”版本。 Notes列描述了LLVM如何使用该包并提供其他详细信息。

Package Version Notes
GNU Make 3.79/3.79.1 Makefile/build processor
GCC >=5.1.0 C/C++ compiler
python >=2.7 Automated test suite
zlib >=1.2.3.4 Compression library

注释:

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

此外,您的编译主机通常会有大量的Unix实用程序。明确地: 

  1. ar-存档库生成器              
  2. bzip2-bz2文件加解压命令              
  3. bunzip2-bzip2的符号连接
  4. chmod-更改文件的权限              
  5. cat-输出串联实用程序              
  6. cp-复制文件             
  7. date-打印当前日期/时间             
  8. echo-打印到标准输出             
  9. egrep-扩展正则表达式搜索实用程序             
  10. find-在文件系统中查找文件/目录              
  11. grep-正则表达式搜索实用程序              
  12. gzip-gz文件加解压命令        
  13. gunzip-gzip的符号连接
  14. install-安装目录/文件              
  15. mkdir-创建目录              
  16. mv-移动(重命名)文件              
  17. ranlib-存档库的符号表生成器              
  18. rm-删除(删除)文件和目录             
  19. sed-用于转换输出的SED流编辑器             
  20. sh-用于生成构建脚本的sh-bourne shell             
  21. tar-用于分发生成的tar磁带存档             
  22. test-在文件系统中测试东西              
  23. unzip-zip文件解压命令
  24. zip-zip文件压缩命令

6.Host C++ Toolchain, both Compiler and Standard Library

LLVM对主机C++编译器非常苛刻,因此会暴露编译器中的错误。我们还试图密切跟踪C++语言和库中的改进和发展。因此,我们需要一个现代主机C++工具链,编译器和标准库,以便建立LLVM。              

LLVM是使用编码标准中记录的C++子集编写的。为了强制使用此语言版本,我们在构建系统中检查最流行的主机工具链以获取特定的最低版本: Clang 3.5,Apple Clang 6.0,GCC 5.1,Visual Studio 2017。

当我们转换到上面列出的新编译器版本时,下面的版本当前是软错误的。目前已知LLVM代码库可以使用以下编译器正确编译,但这在不久的将来会发生变化: Clang 3.1,Apple Clang 3.1,GCC 4.8,Visual Studio 2015 (Update 3)

任何比这些工具链更老的工具都可以工作,但是需要用一个特殊的选项来强制构建系统,而不是真正受支持的主机平台。还请注意,这些编译器的旧版本经常崩溃或错误编译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包含一个bug,它在构建llvm时会导致巨大的链接时间(分钟而不是秒)。我们建议升级到较新版本(2.17.50.0.4或更高版本)。

gnu-binutils 2.19.1gold:这个版本的gold包含一个bug,它在使用位置无关代码构建LLVM时会导致间歇性故障。症状是关于循环依赖性的错误。我们建议升级到较新版本的gold。 

7.Getting a Modern Host C++ Toolchain

本节主要适用于Linux和较旧的BSD。在MacOSX上,您应该有一个足够新的Xcode,否则您可能需要升级。Windows没有“系统编译器”,因此必须安装Visual Studio 2015或MingW64的最新版本。Freebsd 10.0和更新版本有一个现代的clang作为系统编译器。

然而,一些Linux发行版和一些其他或旧的BSD有时具有非常旧的GCC版本。这些步骤试图帮助您升级编译器,即使是在这样的系统上。但是,如果可能的话,我们鼓励您使用最新版本的发行版和满足这些要求的现代系统编译器。注意,安装clang和libc++的早期版本作为宿主编译器是很有诱惑力的,但是直到最近libc++还没有经过很好的测试或设置来构建Linux。因此,本指南建议只使用libstdc++和现代gcc作为引导程序中的初始主机,然后使用clang(以及潜在的libc++)。

第一步是安装最新的gcc工具链。最常见的发行版是UbuntuPrecise,12.04LTS,用户一直在为版本要求而苦苦挣扎。对于这个发行版,一个简单的选择是安装工具链测试ppa并使用它安装现代gcc。在ask-ubuntu堆栈交换和带有更新命令的Github 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引导时将其传递给编译和链接命令。 

8.Getting Started with LLVM

本指南的其余部分旨在帮助您启动和运行LLVM,并提供有关LLVM环境的一些基本信息。              

本指南的后面部分介绍LLVM源代码树的总体布局,使用LLVM工具链的简单示例,以及用于查找有关LLVM的更多信息或通过电子邮件获取帮助的链接。 

9.Terminology and Notation

在本手册中,以下名称用于表示特定于本地系统和工作环境的路径。这些不是您需要设置的环境变量,而是下面文档其余部分中使用的字符串。在下面的任何示例中,只需在本地系统上用适当的路径名替换这些名称。所有这些路径都是绝对路径:

SRC_ROOT

这是llvm源树的顶级目录。

OBJ_ROOT

这是llvm对象树的顶级目录(即放置对象文件和编译程序的树。它可以与src_root相同)

10.从Git下载llvm              

您还可以从git下载llvm的源代码。虽然LLVM项目的官方源代码存储库是Subversion,但我们正在迁移到Git。我们目前建议所有开发人员使用Git进行日常开发。 

注释

在我们正确地调整.gitattribute设置之后,将来不需要通过--config core.autocrlf=false,但在编写本文时Windows用户需要。

简单运行:

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和所有相关子项目的所有源代码、测试目录和文档文件的本地副本。注意,与tarballs不同,它将每个子项目包含在一个单独的文件中,Git存储库将所有项目都包含在一起。              

如果您想要获得一个特定的版本(而不是最新的版本),您可以在克隆存储库之后加上一个一个标记。例如,在上面命令创建llvm-project之后加上git checkout llvmrg-6.0.1。使用git tag -l列出所有这些。 

11.Sending patches

也请阅读开发人员政策。              

我们目前不接受github pull请求,因此您需要通过电子邮件发送补丁给llvm-commits,或者最好通过phabricator发送。              

您通常希望确保您的分支具有单个提交,与您希望发送的审阅相对应,与上游源站/主分支保持最新,并且不包含合并。一旦你有了这个,你就可以使用git-show或git format-patch来输出diff,并将它附加到一个phabricator评论(或一封电子邮件)。              

然而,使用“arcanist”工具通常更容易。安装arcanist后,可以使用以下方法上载最新提交: 

% arc diff HEAD~1

另外,在发送一个补丁进行审查之前,请确保它的格式正确。我们为此使用clang-format,它通过git-clang-format脚本集成了git。在某些系统上,它可能已经安装(或可以通过包管理器安装)。如果是这样,您可以简单地运行它–下面的命令将只格式化在最近的提交中更改的代码:

% git clang-format HEAD~1

请注意,这会修改文件,但不会提交它们–您可能希望运行 

% git commit --amend -a

以便用所有挂起的更改更新上一次提交。              

注释              

如果您的系统上还没有安装clang格式或git clang格式,clang格式二进制文件将与clang一起构建,并且git集成可以从clang/tools/clang-format/git-clang-format运行。 

12.For developers to commit changes from Git

在llvm/utils/git-svn/git-llvm中提供了一个助手脚本。将其添加到路径后,可以使用git llvm push将提交的更改推送到上游。虽然这会创建一个Subversion签出并在引擎盖下对其进行修补,但它不需要您与之交互。 

% export PATH=$PATH:$TOP_LEVEL_DIR/llvm-project/llvm/utils/git-svn/
% git llvm push

在推到Subversion之后的几分钟内,svn提交将被转换回git提交,并进入正式的git存储库。在这一点上,git pull应该在提交更改时返回这些更改。              

您可能希望git pull——重新设置基码,以便将正式的git commit下载回您的存储库。每个提交的SVN修订号可以在提交消息的末尾找到,例如llvm svn:350914。              

您可能还会发现-n标志很有用,比如git llvm push-n。这将运行提交的所有步骤,而不必实际执行提交,并告诉您它会做什么。如果你不确定是否会发生正确的事情,这会很有用。 

13.Checkout via SVN (deprecated)

在我们完全迁移到Git之前,您还可以从官方Subversion存储库中获取代码的新副本。
cd where-you-want-llvm-to-live
只读:svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
读写:svn co https://[email protected]/svn/llvm-project/llvm/trunk llvm
这将在当前目录中创建一个“llvm”目录,并使用LLVM源代码,Makefile,测试目录和文档文件的本地副本放入。
如果您想获得特定版本(而不是最新版本),可以从“tags”目录(而不是“trunk”)中查看。 以下版本位于'tags'目录的以下子目录中:
版本3.5.0及更高版本:RELEASE_350/final等等
版本2.9到3.4:RELEASE_29/final等等
版本1.1到2.8:RELEASE_11等等
版本1.0:RELEASE_1

从存储库下载后,必须在构建之前配置LLVM套件源代码。 此过程使用CMake。 不使用正常的configure脚本链接,CMake以您请求的任何格式生成构建文件以及各种* .inc文件和llvm / include / Config / config.h。
使用格式-D <variable name> = <value>将变量传递给命令行上的cmake。 以下变量是开发LLVM的人员使用的一些常用选项。

变量 目的
CMAKE_C_COMPILER 告诉cmake使用哪个C编译器。 默认情况下,这将是/usr/bin/cc。
CMAKE_CXX_COMPILER 告诉cmake使用哪个C ++编译器。 默认情况下,这将是/usr/bin/c ++。
CMAKE_BUILD_TYPE 告诉cmake您尝试为其生成文件的构建类型。 有效选项包括Debug,Release,RelWithDebInfo和MinSizeRel。 默认为Debug。
CMAKE_INSTALL_PREFIX 指定运行构建文件的安装操作时要定位的安装目录。
LLVM_TARGETS_TO_BUILD 以分号分隔的列表,用于控制将构建哪些目标并将其链接到llvm。 默认列表定义为LLVM_ALL_TARGETS,可以设置为包含树外目标。 默认值包括:AArch64,AMDGPU,ARM,BPF,Hexagon,Mips,MSP430,NVPTX,PowerPC,Sparc,SystemZ,X86,XCore。
LLVM_ENABLE_DOXYGEN 从源代码构建基于doxygen的文档默认情况下禁用它,因为它很慢并且会产生大量输出。
LLVM_ENABLE_PROJECTS 以分号分隔的列表,用于选择要另外构建的其他LLVM子项目。 (仅在使用并排项目布局时有效,例如通过git)。默认列表为空。可以包括:clang,libcxx,libcxxabi,libunwind,lldb,compiler-rt,lld,polly或debuginfo-tests。
LLVM_ENABLE_SPHINX 从源代码构建基于sphinx的文档。默认情况下禁用此选项,因为它很慢并产生大量输出。建议使用Sphinx 1.5或更高版本。
LLVM_BUILD_LLVM_DYLIB 生成libLLVM.so。此库包含一组默认的LLVM组件,可以使用LLVM_DYLIB_COMPONENTS覆盖它们。默认值包含大部分LLVM,并在tools / llvm-shlib / CMakelists.txt中定义。
LLVM_OPTIMIZED_TABLEGEN 构建在LLVM构建期间使用的release tablegen。这可以大大加快调试版本

要配置LLVM,请按照下列步骤操作:

  • 将目录更改为对象根目录:
% cd OBJ_ROOT
  • 使用cmake运行:
% cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/install/path
  [other options] SRC_ROOT

14.编译LLVM Suite源代码
与autotools不同,使用CMake,您的构建类型在配置中定义。 如果要更改构建类型,可以使用以下调用重新运行cmake:

% cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=type SRC_ROOT

在运行之间,CMake保留为所有选项设置的值。 CMake定义了以下构建类型:
Debug
这些构建是默认的。 构建系统将编译未经优化的工具和库,并调试信息并启用断言。

Release
对于这些构建,构建系统将在启用优化的情况下编译工具和库,而不生成调试信息。 CMakes默认优化级别为-O3。 这可以通过在CMake命令行上设置CMAKE_CXX_FLAGS_RELEASE变量来配置。

RelWithDebInfo

这些构建在调试时很有用。 它们使用调试信息生成优化的二进制文件CMakes默认优化级别为-O2。 这可以通过在CMake命令行上设置CMAKE_CXX_FLAGS_RELWITHDEBINFO变量来配置。
配置LLVM后,可以通过输入OBJ_ROOT目录并发出以下命令来构建它:

% make

如果构建失败,请在此处查看您是否使用已知不编译LLVM的GCC版本。
如果您的计算机中有多个处理器,您可能希望使用GNU Make提供的一些并行构建选项。 例如,您可以使用以下命令:

% make -j2

在使用LLVM源代码时,有几个特殊目标非常有用:

make clean:

删除构建生成的所有文件。 这包括目标文件,生成的C / C ++文件,库和可执行文件。

make install

在$PREFIX下的层次结构中安装LLVM头文件,库,工具和文档,使用CMAKE_INSTALL_PREFIX指定,默认为/usr/local。

make docs-llvm-html
如果使用-DLLVM_ENABLE_SPHINX = On配置,则会在OBJ_ROOT/docs/html生成一个包含HTML格式文档的目录。

make docs-llvm-html
如果使用-DLLVM_ENABLE_SPHINX = On配置,则会在OBJ_ROOT/docs/html生成一个包含HTML格式文档的目录。

Cross-Compiling LLVM

可以Cross-Compiling LLVM本身。 也就是说,您可以创建LLVM可执行文件和库,以托管在与构建它们的平台不同的平台上(加拿大跨版本)。 生成用于交叉编译的构建文件CMake提供了一个变量CMAKE_TOOLCHAIN_FILE,它可以定义在CMake测试操作期间使用的编译器标志和变量。
这种构建的结果是可在构建主机上运行但可以在目标上执行的可执行文件。 作为示例,以下CMake调用可以生成针对iOS的构建文件。 这将适用于带有最新Xcode的Mac OS X:

% cmake -G "Ninja" -DCMAKE_OSX_ARCHITECTURES="armv7;armv7s;arm64"
  -DCMAKE_TOOLCHAIN_FILE=<PATH_TO_LLVM>/cmake/platforms/iOS.cmake
  -DCMAKE_BUILD_TYPE=Release -DLLVM_BUILD_RUNTIME=Off -DLLVM_INCLUDE_TESTS=Off
  -DLLVM_INCLUDE_EXAMPLES=Off -DLLVM_ENABLE_BACKTRACES=Off [options]
  <PATH_TO_LLVM>

注意:由于iOS SDK的限制,在构建iOS时需要传递一些额外的标志。
检查如何使用Clang/LLVM和Clang文档交叉编译Clang/LLVM,了解如何进行交叉编译以获得有关交叉编译的更多信息。

15.The Location of LLVM Object Files

LLVM构建系统能够在多个LLVM构建中共享单个LLVM源树。 因此,可以使用相同的源树为多个不同的平台或配置构建LLVM。
将目录更改为LLVM目标文件应存在的位置:

% cd OBJ_ROOT

使用make运行:

% cmake -G "Unix Makefiles" SRC_ROOT

LLVM构建将在OBJ_ROOT下创建与LLVM源树匹配的结构。 在源树中存在源文件的每个级别,OBJ_ROOT中都有相应的CMakeFiles目录。 在该目录下面有另一个名称以.dir结尾的目录,在该目录下您可以找到每个源的目标文件。

例如:

% cd llvm_build_dir
% find lib/Support/ -name APFloat*
lib/Support/CMakeFiles/LLVMSupport.dir/APFloat.cpp.o

16.Optional Configuration Items

如果您在支持binfmt_misc模块的Linux系统上运行,并且您在系统上具有root访问权限,则可以将系统设置为直接执行LLVM bitcode文件。 要执行此操作,请使用如下命令(如果您已在使用该模块,则可能不需要第一个命令):

% mount -t binfmt_misc none /proc/sys/fs/binfmt_misc
% echo ':llvm:M::BC::/path/to/lli:' > /proc/sys/fs/binfmt_misc/register
% chmod u+x hello.bc   (if needed)
% ./hello.bc

这允许您直接执行LLVM bitcode文件。 在Debian上,您也可以使用此命令代替上面的'echo'命令:

% sudo update-binfmts --install llvm /path/to/lli --magic 'BC'

17.Directory Layout

有关LLVM源代码库的一个有用信息来源是http://llvm.org/doxygen/上提供的LLVM doxygen文档。 以下是代码布局的简要介绍:

目录 目录内容
llvm/examples 使用LLVM IR和JIT的简单例子
llvm/include 从LLVM库导出的公共头文件。
llvm/include/llvm 所有LLVM特定的头文件,以及LLVM不同部分的子目录:Analysis,CodeGen,Target,Transforms等...
llvm/include/llvm/Support 与LLVM一起提供的通用支持库,但不一定是特定于LLVM的。例如,一些c++ STL实用程序和处理库的命令行选项在这里存储头文件。
llvm/include/llvm/Config 由cmake配置的头文件。它们封装“标准”UNIX和C头文件。源代码可以包含这些头文件,这些头文件自动处理cmake生成的条件#include。
llvm/lib

大多数源文件都在这里。通过将代码放入库中,LLVM使得在工具之间共享代码变得很容易。

llvm/lib/IR/ 核心LLVM源文件,实现核心类,如指令和BasicBlock。
llvm/lib/AsmParser/ LLVM汇编语言解析器库的源代码。
llvm/lib/Bitcode/ 用于读取和写入位码的代码。
llvm/lib/Analysis/ 各种程序分析,如调用图、归纳变量、自然循环识别等。
llvm/lib/Transforms/ irto - ir程序转换,如主动死代码消除、稀疏条件常数传播、内联、循环不变代码运动、死全局消除等。
llvm/lib/Target/ 描述用于代码生成的目标体系结构的文件。例如,llvm/lib/Target/X86包含X86机器描述。
llvm/lib/CodeGen/ 代码生成器的主要部分:指令选择器、指令调度和寄存器分配。
llvm/lib/MC/ (FIXME: T.B.D.) ....吗?
llvm/lib/ExecutionEngine/ 用于在解释和jit编译的场景中在运行时直接执行位代码的库。
llvm/lib/Support/ 对应于llvm/include/ADT/和llvm/include/Support/中的头文件的源代码。
llvm/projects projects不是严格意义上的LLVM的一部分,而是随LLVM一起发布的。这也是创建您自己的基于LLVM的项目的目录,这些项目利用LLVM构建系统。
llvm/test 特性和回归测试以及对LLVM基础设施的其他完整性检查。它们的目的是快速运行并覆盖很多领域,而不是面面俱到。
test-suite 为LLVM提供全面的正确性、性能和基准测试套件。这来自于一个单独的git存储库<https://github.com/llvm/llvm-test-suite>,因为它包含了大量第三方代码在各种许可证之下。有关详细信息,请参阅测试指南文档。
llvm/tools 由上述库构建的可执行程序,构成用户界面的主要部分。您总是可以通过键入tool_name -help来获得工具的帮助。下面是对最重要的工具的简要介绍。更详细的信息在命令指南中。
bugpoint bugpoint用于调试优化传递或代码生成后端,方法是将给定的测试用例缩小到仍然会导致问题(无论是崩溃还是错误编译)的最小传递和/或指令数量。有关使用bugpoint的更多信息,请参见 HowToSubmitABug.html。
llvm-ar 归档器生成一个包含给定LLVM位代码文件的归档文件,可以选择使用索引来加快查找速度。

llvm-as

汇编程序将人类可读的LLVM程序集转换为LLVM位代码。
llvm-dis 反汇编程序将LLVM位代码转换为人类可读的LLVM程序集。
llvm-link 毫无疑问,LLVM -link将多个LLVM模块链接到一个程序中。
lli lli是LLVM解释器,它可以直接执行LLVM位码(虽然很慢……)。对于支持它的架构(目前是x86、Sparc和PowerPC),默认情况下,lli将作为即时编译器(如果功能是在其中编译的)运行,并且执行代码的速度将比解释器快得多。
llc llc是LLVM后端编译器,它将LLVM位代码转换为本机代码汇编文件。
opt opt读取LLVM位代码,将一系列LLVM应用于LLVM转换(在命令行中指定),并输出结果位代码。“opt -help”是获取LLVM中可用的程序转换列表的好方法。opt还可以对输入LLVM位码文件运行特定的分析并打印结果。主要用于调试分析,或者熟悉分析的功能。
llvm/utils 使用LLVM源代码的实用程序;有些是构建过程的一部分,因为它们是基础设施部分的代码生成器
codegen-diff codegen-diff发现LLC生成的代码和LLI生成的代码之间的差异。如果您正在调试其中一个,假设另一个生成正确的输出,那么这将非常有用。要获得完整的用户手册,请运行`perldoc codegen-diff'
emacs/ Emacs和XEmacs语法高亮显示LLVM程序集文件和TableGen描述文件。有关使用它们的信息,请参阅自述文件。
getsrcs.sh 查找和输出所有非生成的源文件,如果希望跨目录进行大量开发而不想查找每个文件,那么这非常有用。使用它的一种方法是运行,例如:xemacs的utils/getsources。从LLVM源代码树的顶部开始执行sh '。
llvmgrep 对LLVM中的每个源文件执行一个egrep -H -n,并将llvmgrep命令行上提供的正则表达式传递给它。这是搜索特定正则表达式的源库的一种有效方法。
TableGen/ 包含用于从公共TableGen描述文件生成寄存器描述、指令集描述甚至汇编器的工具。
vim/ vim语法高亮显示LLVM程序集文件和TableGen描述文件。请参阅自述文件了解如何使用它们。

18.An Example Using the LLVM Tool Chain

本节给出一个使用带Clang前端的LLVM的示例。

% clang hello.c -o hello

19.Example with clang

  • 首先,创建一个简单的C文件,将其命名为“hello.c”:
#include <stdio.h>

int main() {
  printf("hello world\n");
  return 0;
}
  • 接下来,将C文件编译为本机可执行文件:
% clang hello.c -o hello

注释

默认情况下,clang的工作方式与gcc类似。标准-s和-c参数正常工作(分别生成本机.s或.o文件)。

  • 接下来,将C文件编译成LLVM比特码文件:
% clang -O3 -emit-llvm hello.c -c -o hello.bc

-emit llvm选项可以与-s或-c选项一起使用,分别为代码发出llvm.ll或.bc文件。这允许您在比特码文件上使用标准的llvm工具。

  • 可以用以下两种形式运行程序:
% ./hello
% lli hello.bc

第二个例子展示了如何调用llvm jit,lli。

  • 使用llvm dis实用程序查看llvm程序集代码:
% llvm-dis < hello.bc | less
  • 使用LLC代码生成器将程序编译为本机程序集:
% llc hello.bc -o hello.s
  • 将本机汇编语言文件汇编到程序中:
% /opt/SUNWspro/bin/cc -xarch=v9 hello.s -o hello.native   # On Solaris
% gcc hello.s -o hello.native                              # On others
  • 执行本机代码程序:
% ./hello.native

请注意,使用clang直接编译为本机代码(即当-emit llvm选项不存在时)可以为您执行步骤6/7/8。

20.Common Problems

如果您在构建或使用LLVM时遇到问题,或者您对LLVM有任何其他一般性问题,请参阅“常见问题”页面。

猜你喜欢

转载自blog.csdn.net/zhang14916/article/details/89288196