LLVM的安装步骤实战

目录

1. 准备环境

1.1 安装必备软件包

1.2 配置Git

2. 用CMake构建

2.1 克隆代码库

2.2 创建构建目录

2.3 生成构建系统文件

3. 自定义构建

3.1 CMake定义的变量

3.2  LLVM定义的变量

4. 总结

1. 准备环境

首先操作系统可以是Linux、FreeBSD、macOS或Windows。

同时硬件磁盘需要准备至少30GB的空余空间。

需要必备软件工具的版本如下表:

工具名称

作用

版本

git

管理源代码

1.17.10

CMake

构建文件生成器

3.13.4

C/C++

标准的编译器和标准库

C++14

Python

生成构建文件并运行测试套件

3.6

GNU Make

构建工具

3.79

1.1 安装必备软件包

要安装必备软件最简单的方法是使用操作系统中的包管理器。下面将为主流的操作系统安装软件准备相应的命令行。

对于这里的场景,用make替换命令中的ninja就可以了

(1)Ubuntu

Ubuntu 20.04使用APT包管理器。大多数基础设施已经安装完毕,只缺少开发工具。输入以下命令:

$ sudo apt install -y gcc g++ git cmake make-build

(2)Fedora和RedHat

Fedora 33和RadHat Enterprise Linux 8.3的包管理器称为DNF。和Ubuntu一样,大多数基本实用程序都已经安装好了。输入以下命令:

$ sudo dnf install -y gcc gcc-c++ git cmake make-build

(3)FreeBSD

在FreeBSD 12或更高版本上,您必须使用PKG包管器。FreeBSD与基于Linux的系统的不同之处在于,Clang是首选编译器。输入以下命令:

$ sudo pkg install -y clang git cmake make

(4) OS X

对于OS X上的开发,最好从Apple商店安装Xcode。虽然本书中没有使用Xcode IDE,但它附带了所需的C/C++编译器和实用程序。要安装其他工具,可以使用Homebrew软件包管理器用(https://brew.sh/)。输入以下命令:

$ brew install git cmake make

(5) Windows

OS X一样,Windows没有包管理器。安装所有软件的最简单方法是使用Chocolately(https://chocolatey.org/)包管理器。输入以下命令:

$ choco install visualstudio2019buildtools cmake make git gzip bzip2 gnuwin32-coreutils.install

请注意,这只安装来自Visula Studio 2019的构建工具。如果你想获得Community Edition(包含IDE),那么你必须安装visualstdio2019community包而不是visualstudio2019 buildtools。Visula Studio 201安装的一部分是VS 2019的x64 Native Tools命令提示符。使用此命令提示符时,编译器将自动添加到搜索路径中。

1.2 配置Git

LLVM项目使用Git进行版本控制。如果没有使用过Git,那么应该先做一些Git的基本配置(包括用户名和邮件地址)。如果提交更改,将使用以下两条命令:

$ git config --global user.email "jane@email.org"

$ git config --global user.name "Jane"

2. 用CMake构建

准备好构建工具之后,就可以从GitHub拷贝出所有的LLVM项目。所有平台上执行次操作的命令基本相同,但在Windows上,建议关闭对行结束符的自动转译。

2.1 克隆代码库

在所有非Windows平台上,输入以下命令克隆代码库:

$ git clone https://github.com/llvm/llvm-project.git

在Windows上,必须添加选项以禁用自动转译行结束符。在这里输入以下内容:

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

这将最新的源代码从GitHub克隆到一个名为llvm-project的本地目录中。现在,进入llvm-project目录:

$ cd llvm-project 

这个目录包含所有的LLVM项目,每个项目都有自己的目录。最值得注意的是,LLVM核心库位于LLVM子目录中。LLVM项目使用分支来进行后续版本开发(“release/12x”)和标记(“llvmorg-12.0.0”)来标记某个版本。通过前面的clone命令,可以获得当前的开发状态。创建一个新的分支,输入以下命令:

$ git checkout -b llvmorg-12

这样就克隆了整个LLVM源代码,并开启一个新分支。

2.2 创建构建目录

与许多其他项目不同,LLVM不支持内联构建,需要单独的构建目录。可以在llvm-project目录中创建一个目录。先进入llvm-project目录:

$ cd llvm-project

然后,为了简单起见,创建一个名为build的构建目录。应该使用以下命令:

$ mkdir build

然后,切换到构建目录:

$ cd build

现在,就可以在这个目录中使用CMake工具创建系统文件。

2.3 生成构建系统文件

要生成将使用make编译LLVM和Clang的构建系统文件,请运行以下命令:

$ cmake -G Unix Makefiles -DLLVM_ENABLE_PROJECTS=clang ../llvm

-G选项告诉CMake要为哪个系统生成构建文件。最常用的选项如下:

• Ninja: 对应Ninja的构建系统

• Unix Makefiles: 对应GNU Make

• Visual Studio 15 VS2017和Visual Studio 16 VS2019: 对应Visual Studio和MS Build

• Xcode: 对应Xcode工程

可以使用-D选项设置各种变量来影响生成过程。通常,以CMAKE(由CMAKE定义)或LLVM(由LLVM定义)作为前缀。使用LLVM_ENABLE_PROJECTS=clang变量设置,CMake为LLVM之外的Clang生成构建文件。命令的最后一部分指定LLVM核心库源代码的位置。

当生成了构建文件,LLVM和Clang可以用以下命令编译:

$ make

根据硬件资源的不同,该命令的运行时间在15分钟(具有大量CPU内核、内存和快速存储的服务器)到数小时(内存有限的双核Windows笔记本)之间。默认情况下,make使用了所有可用的CPU核。这有利于提高编译速度,但可能会阻止其他任务的运行。例如,在Windows笔记本上,make在运行时几乎不能上网。幸运的是,可以使用-j选项限制资源的使用。

假设您有四个可用的CPU核,而make应该只使用两个(因为有并行任务要运行)。在这里,应该使用以下命令进行编译:

$ make -j2

当编译完成,可以运行测试套件,以检查是否一切正常:

$ make check-all

同样,该命令的运行时因可用硬件资源的不同而有很大差异。make检查目标运行所有测试用例,为每个包含测试用例的目录生成目标。使用check-llvm(而不是check-all)是运行LLVM测试,而不是Clang测试,check-llvm-codegen只运行来自LLVM的CodeGen目录中的测试(即llvm/test/CodeGen目录)。

也可以做一个快速的手动检查。使用的LLVM的llc,即LLVM编译器。如果使用-version选项,会显示它的LLVM版本,主机CPU,以及它所支持的所有架构:

$ bin/llc -version

如果编译LLVM时有困难,那么可以参考LLVM系统文档入门中的常见问题部分(https://llvm.org/docs/GettingStarted.html#common-problems),以获得常见问题的解决方案。

最后,安装可执行文件:

$ make install

在类Unix系统上,安装目录是/usr/local。在Windows下,使用C:\Program File\LLVM。当然可以修改,下一节将说明如何操作。

3. 自定义构建

CMake系统使用CMakeLists.txt文件对项目进行描述。顶层文件在llvm目录中,也就是llvm/CMakeLists.txt,其他目录还包含CMakeLists.txt,在构建文件生成期间会递归地包含这些文件。

根据项目描述中提供的信息,CMake检查已经安装了哪些编译器,检测库和符号,并创建构

建系统文件,如build.ninja或Makefile(取决于选择的生成器)。还可以定义可重用的模块,例如检测LLVM是否已安装的函数。这些脚本被放置在特殊的cmake目录

(llvm/cmake)中,在生成过程中会自动搜索该目录。

  构建过程可以通过定义CMake变量来定制。命令行选项-D将为一个变量设置值,这些变量会在CMake脚本中使用。CMake自己定义的变量几乎总是以CMake 为前缀,这些变量可以在所有项目中使用。由LLVM定义的变量前缀为LLVM ,但只能在项目定义中包含LLVM时使用。

3.1 CMake定义的变量

有些变量是用环境变量的值初始化的。最值得注意的是CC和CXX,它们定义了用于构建的C和C++编译器。CMake尝试使用当前的shell搜索路径自动定位C和C++编译器,并选择找到的第一个编译器。如果你安装了多个编译器,比如:gcc和Clang或不同版本的Clang,那么默认找到的可能不是预期构建LLVM的编译器。

  假设想使用clang9作为C编译器,使用clang++9作为C++编译器。可以在Unix shell中使用Cmake:

$ CC=clang9 cXX=clang++9 cmake ../llvm

它会设置cmake调用的环境变量的值。如果需要,可以为编译器指定绝对路径。

CC是CMAKE_C_COMPILER cmake变量的默认值,而CXX是畃CMAKE_CXX_COMPILER cmak变量的默认值。您可以直接设置CMake变量,而不使用环境变量。这与前面的调用相同:

$ cmake -DCMAKE_C_COMPILER=clang9\
        -DCMAKE_CXX_COMPILER=clang++9 ../llvm

CMake定义的其他常用变量如下:

• CMAKE_INSTALL_PREFIX:在安装过程中添加到每个路径上的路径前缀。Unix上默认为/usr/local,Windows上默认为C:\Program Files\。如果要在/opt/LLVM目录下安装LLVM,必须指定-DCMAKE_INSTALL_PREFIX,可执行文件复制到/opt/llvm/bin,库文件复制到/opt/llvm/lib,以此类推。

• CMAKE_BUILD_TYPE:不同类型的构建需要不同的设置,例如:调试构建需要指定用于生成调试符号的选项,并且通常是针对系统库的调试版本进行链接。相比之下,发布版本使用针对库的生产版本的优化标志和链接。此变量仅用于只能处理一种构建类型的构建系统,如Ninja或Make。对于IDE构建系统,必须使用IDE的机制在构建类型之间进行切换。可能的值如下:

• DEBUG: 使用调试符号构建

• RELEASE: 以速度优化为主的构建

• RELWITHDEBINFO: 使用调试符号的发布构建

• MINSIZEREL: 以优化生成文件大小为主的构建

默认的构建类型是DEBUG。要构建为发布版本,必须指定

-DCMAKE_BUILD_TYPE=RELEASE

• CMAKE_C_FLAGS和CMAKE_FLAGS: 当我们编译C和C++源文件时,这些是额外的标志。初始值取自CFLAGS和CXXFLAGS环境变量,可以替代变量使用。

• CMAKE_MODULE_PATH指定在CMAKE模块中搜索的附加目录。在搜索默认目录之前搜索指定的目录,以分号分隔的目录列表。

• 如果没有找到PYTHON解释器,或者如果安装了多个版本的PYTHON解释器。在CMake选择了错误的解释器时,可以将该变量设置为正确PYTHON二进制文件的路径。这个变量只有在包含了CMake的Python模块时才会生效(对于LLVM也是如此)。

CMake为变量提供了内置帮助。--help-variable var选项打印var变量的帮助信息。例如,您可以输入以下命令来获取CMAKE_BUILD_TYPE的帮助:

$ cmake --help-variable CMAKE_BUILD_TYPE

也可以用下面的命令列出所有的变量(这个清单很长):

$ cmake --help-variablelist

3.2  LLVM定义的变量

LLVM定义的变量的工作方式与CMake定义的变量相同,但没有内置帮助。常用的变量如下:

• LLVM_TARGETS_TO_BUILD: LLVM支持不同的CPU架构。默认情况下,构建所有目标。使用此变量指定要构建的目标列表,由分号分隔。目前支持的目标有AArch64、AMDGPU、ARM、BPF、Hexagon、Lanai、Mips、MSP430、NVPTX、PowerPC、RISCV、Sparc、SystemZ、WebAssenby、X86、XCore。All可以作为All目标的简写,并且名称区分大小写。

若要只启用PowerPC和SystemZ目标,必须指定

-DLLVM_TARGETS_TO_BUILD="PowerPC;SystemZ"

• LLVM_ENABLE_PROJECTS:这是一个要构建的项目列表,由分号分隔。项目的源代码必须与llvm目录在同一级别(并排布局)。当前列表是clang, clangtools-extra, compiler-rt, debuginfo-tests, lib, libclc, libcxx, libcxxabi, libunwind, lld, lldb, llgo, mlir, openmp, parallel-libs, polly和pstl。

All可以作为此列表中的所有项目的简写。要和LLVM一起构建Clang和llgo,必须指定

-DLLVM_ENABLE_PROJECTS="Clang;llgo"

• LLVM_ENABLE_ASSERTIONS: 如果设置为ON,则启用断言检查。这些检查有助于发现错误,在开发过程中非常有用。对于DEBUG版本,默认值为ON,否则为OFF。要打开断言检查(对于RELEASE版本),必须指定

-DLLVM_ENABLE_ASSERTIONS=ON

• LLVM_ENABLE_EXPENSIVE_CHECKS : 这启用了一些检查,会降低编译速度或消耗大量内存,默认值为OFF。要打开这些检查,必须设置

-DLLVM_ENABLE_EXPENSIVE_CHECKS=ON。

• LLVM_APPEND_VC_REV: llc等LLVM工具显示它们所基于的LLVM版本(如果提供了version命令行选项)。此版本信息基于LLVM_REVISION C宏。默认情况下,不仅LLVM版本,最新提交的Git哈希值也是版本信息的一部分。如果您正在跟踪主分支的开发,这将非常方便,因为它清楚地表明了该工具是基于哪个Git提交的。如果不是必需的,可以使用下面指令关闭

-DLLVM_APPEND_VC_REV=OFF

LLVM_ENABLE_THREADS:如果检测到线程库(通常是pthreads库),LLVM会自动包含线程支持。本例中,LLVM假定编译器支持线程本地存储(TLS)。如果不想要线程支持或者你的编译器不支持TLS,那么可以使用来下面命令关闭它

-DLLVM_ENABLE_THREADS=OFF

• LLVM_ENABLE_EH: LLVM项目不使用C++异常处理,所以默认关闭异常支持。此设置可能与您的项目正在链接的其他库不兼容。如果需要,可以通过指定-DLLVM_ENABLE_EH=ON来启用异常支持。

• LLVM_ENABLE_RTTI: LLVM使用一个轻量级的、自构建的系统来提供运行时类型信息。默认情况下,c++ RTTI的生成是关闭的。与异常处理支持一样,这可能与其他库不兼容。要开启c++ RTTI的生成,必须设置-DLLVM_ENABLE_RTTI=ON。

• LLVM_ENABLE_WARNINGS: 如果可能的话,编译LLVM应该不会产生任何警告消息。默认情况下,打印警告消息的选项是打开的。要关闭它,必须设置-DLLVM_ENABLE_WARNINGS=OFF。

• LLVM_ENABLE_PEDANTIC: LLVM源文件应该符合C/ c++标准。因此,默认情况下启用了对源的学究式检查。如果可能,也禁用编译器特定的扩展。要关闭此设置,必须指定

-DLLVM_ENABLE_PEDANTIC =OFF

•LLVM_ENABLE_WERROR: 如果设置为ON,则所有警告都视为错误——发现警告,编译就会中止。它有助于在源代码中找到所有剩余的警告。默认情况下,是关闭的。要打开它,必须指定

• LLVM_OPTIMIZED_TABLEGEN:通常,tablegen工具与LLVM的其他部分使用相同的选项构建。同时,tablegen用于生成大部分代码生成器。因此,tablegen在调试构建中要慢得多,从而显著增加了编译时间。如果将此选项设置为ON,则tablegen编译时会启用优化,即使是在调试构建中,也可能会减少编译时间,默认为OFF。要打开此选项,必须指定

-DLLVM_OPTIMIZED_TABLEGEN=ON

• LLVM_USE_SPLIT_DWARF: 如果构建编译器是gcc或Clang,那么打开这个选项编译器将在单独的文件中生成DWARF调试信息。减小的对象文件大小大大减少了调试构建的链接时间,默认为OFF。要开启此功能,必须指定

-DLLVM_USE_SPLIT_DWARF=ON

LLVM定义了更多的CMake变量。可以在CMakeLLVM文档中找到完整的列表 (https://

releases.llvm.org/12.0.0/docs/CMake.html#llvm-specific-variables),前面的列表只包含

常用的一些。

 

4. 总结

本文中,我们准备了开发机器来编译LLVM,克隆了LLVM GitHub代码库,并编译了LLVM和Clang。

构建过程可以使用CMake变量进行定制。还学习了相关的变量以及如何更改它们。有了这些知识,就可以根据需要调整LLVM的构建。

后面的文章中,我们将更详细地研究LLVM代码库的内容。将了解其中包含哪些项目以及这些项目是如何构建的。然后,将使用LLVM库创建自己的项目。最后,将学习如何为不同的CPU架构编译LLVM。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/311080.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python基础(二十四、JSON和pyecharts)

文章目录 一、JSON1.JSON介绍2.JSON格式数据转化3.示例 二、pyecharts1.安装pyecharts包2.查看官方示例 三、开发示例 一、JSON 1.JSON介绍 JSON是一种轻量级的数据交互格式,采用完全独立于编程语言的文本格式来存储和表示数据(就是字符串)…

邻接矩阵、可达性矩阵、完全关联矩阵、可达性矩阵的计算

邻接矩阵:很简单,就是两个点有关系就是1,没有关系就是0 可达性矩阵:非常简单,两点之间有路为1,没有路为0 可发行矩阵的计算:有n个元素,初始可达性矩阵为A,那么最终的矩阵…

实战环境搭建-linux下安装tomcat

安装tomcat Index of /dist/tomcat/tomcat-9/v9.0.8/bin 下载apache-tomcat-9.0.8.tar.gz,可以使用wget; 2、将压缩包tar -zxvf apache-tomcat-9.0.8.tar.gz解压到/home/tomcat 3、修改环境变量 vi /etc/profile export JAVA_HOME/home/java/jdk1.8.0_221 expo…

C++ 深度优先搜索DFS || 模版题:排列数字

给定一个整数 n ,将数字 1∼n 排成一排,将会有很多种排列方法。 现在,请你按照字典序将所有的排列方法输出。 输入格式 共一行,包含一个整数 n 。 输出格式 按字典序输出所有排列方案,每个方案占一行。 数据范围 1…

力扣热题 100

文章目录 哈希双指针滑动窗口子串普通数组矩阵链表二叉树图论回溯二分查找栈堆贪心算法动态规划多维动态规划技巧 哈希 双指针 移动零 class Solution {public void moveZeroes(int[] nums) {int k 0;for(int i 0;i < nums.length; i){if(nums[i] ! 0) {nums[k] nums[…

行为型设计模式——策略模式

策略模式 策略模式非常简单&#xff0c;只需要将策略或者某个算法定义成一个类&#xff0c;然后传给需要使用的对象即可。**定义&#xff1a;**该模式定义了一系列算法&#xff0c;并将每个算法封装起来&#xff0c;使它们可以相互替换&#xff0c;且算法的变化不会影响使用算…

【ITK库学习】使用itk库进行图像分割(四):水平集分割

目录 1、水平集2、itkFastMarchingImageFilter 快速步进分割3、itkShapeDetectionLevelSetImageFilter 快速步进分割 1、水平集 水平集是跟踪轮廓和表面运动的一种数字化方法。基于图像的亮度均值、梯度、边缘特征的微分计算&#xff0c;进行水平集分割。在itk中&#xff0c;所…

1.10 Unity中的数据存储 JSON

一、介绍 Json是最常用也是目前用的比较多的一种&#xff0c;超轻量级&#xff0c;可便捷性使用&#xff0c;平时用到比较多的都是解析Json和往Json中添加数据、修改数据等等JSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格式&#xff0c;它基于ECMAScr…

git 使用 submodule 如何指定分支

写在前面, 作为一个前端我是不喜欢使用 submodule的, 我更喜欢 npm 包的管理方式。 首次添加子模块 git submodule add -b <branch> <remote> <path> 不指定分支就不传 -b <branch> <branch> 分支名<remote> 仓库地址<path> 子模块…

Unity中URP下抓屏的 开启 和 使用

文章目录 前言一、抓屏开启1、Unity下开启抓屏2、Shader中开启抓屏 二、抓屏使用1、设置为半透明渲染队列&#xff0c;关闭深度写入2、申明纹理和采样器3、在片元着色器使用请添加图片描述 三、测试代码 前言 我们在这篇文章中看一下&#xff0c;URP下怎么开启抓屏。 一、抓屏…

兴业证券分布式数据库云应用实践

数据库技术作为信息技术应用创新过程中的一项重要技术&#xff0c;其面临的难题也是亟需解决的关键问题。兴业证券在《集团五年金融科技规划》中提出&#xff0c;要以信息技术应用创新架构评审为抓手&#xff0c;制定信息技术应用创新规划和建设方案&#xff0c;以高可用性、开…

LeetCode+ 56 - 60

合并区间 双指针算法、位运算、离散化、区间合并_小雪菜本菜的博客-CSDN博客 class Solution { public:vector<vector<int>> merge(vector<vector<int>>& a) {vector<vector<int>> res;if(a.empty()) return res;sort(a.begin(),a.en…

10款强大的iPhone微信恢复软件:轻松恢复丢失的微信数据

微信已成为近年来最受欢迎的消息和社交媒体平台之一。它在全球拥有数百万用户&#xff0c;让人们能够联系、分享时刻并进行各种交易。随着微信的普及&#xff0c;对全面恢复解决方案的需求从未如此之大。本文探讨了专为 iPhone 用户设计的十款顶级微信恢复软件选项。每个软件都…

别不信,搭建企业知识库后真的效率翻倍了

在当今信息时代&#xff0c;知识是最宝贵的财富。一个企业要想越办越大&#xff0c;就需要保证信息的透明度和流通率。而搭建一套企业知识库&#xff0c;就能实现这个目标。今天我们就来聊聊为什么建立企业知识库后&#xff0c;你的工作效率会大大提高。同时&#xff0c;我们会…

智慧医院之定位导航解决方案

移动端LBS应用 通过绘制院方各楼栋各层平面图,利用无线/蓝牙技术可对终端进行实时定位,方便病人、家属等就医,提高就医体验,减少工作人员工作量,减少医患冲突,打造智慧医院。 移动端的LBS位置应用,可分为医院的室内地图展现、室内地图搜索、室内导航、室内定位、室内位…

x-cmd pkg | agg - asciinema gif 生成器

目录 简介首次用户功能特点竞品和相关作品进一步阅读 简介 由 asciinema 团队开发的 asciinema gif 生成器&#xff0c;用于将 asciinema 生成的 asciicast 文件转化为 GIF 文件&#xff0c;具有精确的帧定时&#xff0c;且支持指定字体和颜色主题&#xff0c;能生成更为精美的…

JavaScript系列——闭包

文章目录 闭包定义词法作用域闭包示例使用场景创建私有变量ES5 中&#xff0c;解决循环变量的作用域问题 小结 闭包定义 闭包&#xff0c;是函数及其关联的周边环境的引用的组合&#xff0c;在闭包里面&#xff0c;内部函数可以访问外部函数的作用域&#xff0c;而外部函数不能…

江山易改本性难移之ZYNQ SDK QSPI固化bug及其解决方法

之前在Vivado2018.3通过QSPI方式固化程序时出现问题&#xff0c;显示flash擦除成功&#xff0c;但最后总是不能写入到flash中。 查资料发现从VIVADO 2017.3版本开始&#xff0c;Xilinx官方为了使Zynq-7000和Zynq UltraScale 实现流程相同&#xff0c;在QSPI FLASH使用上做了变化…

【数模百科】一篇文章讲清楚层次分析法的原理和解法步骤

本文节选自 层次分析法原理 - 数模百科&#xff0c;如果你想了解更多关于层次分析法的信息&#xff0c;请移步数模百科。 层次分析法&#xff08;Analytic Hierarchy Process&#xff0c;简称AHP&#xff09;是一种解决复杂决策问题的方法。这个方法是由美国运筹学家托马斯萨蒂…

Java 常见缓存详解以及解决方案

一. 演示Mybatis 一级缓存 首先我们准备一个接口 两个实现的方法&#xff0c; 当我们调用这个queryAll&#xff08;&#xff09;方法时我们需要调用selectAll&#xff08;&#xff09;方法来查询数据 调用此接口实现效果 这个时候我们就可以发现了问题&#xff0c;我们调用方法…