导航:首页 > 源码编译 > 编译llvm依赖

编译llvm依赖

发布时间:2023-01-21 06:47:16

1. 如何使用ninja快速编译LLVM和Clang

1,Build llvm/clang/lldb/lld 3.5.0等组件

1.0 准备:

至少需要从llvm.org下载llvm, cfe, lldb, compiler-rt,lld等3.5.0版本的代码。

$tar xf llvm-3.5.0.src.tar.gz

$cd llvm-3.5.0.src

$mkdir -p tools/clang
$mkdir -p tools/clang/tools/extra
$mkdir -p tools/lld
$mkdir -p projects/compiler-rt

$tar xf cfe-3.5.0.src.tar.xz -C tools/clang --strip-components=1
$tar xf compiler-rt-3.5.0.src.tar.xz -C projects/compiler-rt --strip-components=1
$tar xf lldb-3.5.0.src.tar.xz -C tools/clang/tools/extra --strip-components=1
$tar xf lld-3.5.0.src.tar.xz -C tools/lld --strip-components=1
1.1 【可选】使用clang --stdlib=libc++时,自动添加-lc++abi。

libc++组件可以使用gcc libstdc++的supc++ ABI,也可以使用c++abi,cxxrt等,实际上自动添加-lc++abi是不必要的,这里这么处理,主要是为了方便起见。实际上完全可以在“clang++ -stdlib=libc++”时再手工添加-lc++abi给链接器。

这里涉及到链接时DSO隐式还是显式的问题,早些时候ld在链接库时会自动引入由库引入的依赖动态库,后来因为这个行为的不可控性,所以ld链接器的行为做了修改,需要显式的写明所有需要链接的动态库,才会有手工添加-lc++abi这种情况出现。

2. 如何利用LLVM写一个编译器

书籍请参考编译原理的龙书,以及flex,bison,llvm的manual。
如何写我可以给你一个大致的流程,
编译器由词法分析器->语法分析器->中间代码生成器->后端组成。
用C语言写编译器一般可以按照以下步骤:
1.使用flex生成词法分析器。(flex可以通过自己编写的描述文件来自动生成词法分析器)
2.使用bison生成语法分析器。(bison可以通过自己编写的描述文件来自动生成语法分析器)
3.通过语法分析器得到输入代码的语法树表示。
4.编写遍历函数遍历语法树生成中间代码。(这里推荐使用LLVM的中间代码表示)
5.利用LLVM工具集来编译执行所得到的中间代码。

3. 编译器二:LLVM和GCC的区别

GCC: GNU Compiler Collection
GCC属于传统编译器,传统编译器的工作原理基本上都是三段式的,可以分为前端(Frontend)、优化器(Optimizer)、后端(Backend)。前端负责解析源代码,检查语法错误,并将其翻译为抽象的语法树(Abstract Syntax Tree)。优化器对这一中间代码进行优化,试图使代码更高效。后端则负责将优化器优化后的中间代码转换为目标机器的代码,这一过程后端会最大化的利用目标机器的特殊指令,以提高代码的性能。
事实上,不光静态语言如此,动态语言也符合上面这个模型,例如Java。Java Virtual Machine也利用上面这个模型,将Java代码翻译为Java bytecode。这一模型的好处是,当我们要支持多种语言时,只需要添加多个前端就可以了。当需要支持多种目标机器时,只需要添加多个后端就可以了。对于中间的优化器,我们可以使用通用的中间代码。
这种三段式的结构还有一个好处,开发前端的人只需要知道如何将源代码转换为优化器能够理解的中间代码就可以了,他不需要知道优化器的工作原理,也不需要了解目标机器的知识。这大大降低了编译器的开发难度,使更多的开发人员可以参与进来。
虽然这种三段式的编译器有很多有点,并且被写到了教科书上,但是在实际中这一结构却从来没有被完美实现过。做的比较好的应该属Java和.NET虚拟机。虚拟机可以将目标语言翻译为bytecode,所以理论上讲我们可以将任何语言翻译为bytecode,然后输入虚拟机中运行。但是这一动态语言的模型并不太适合C语言,所以硬将C语言翻译为bytecode并实现垃圾回收机制的效率是非常低的。
GCC也将三段式做的比较好,并且实现了很多前端,支持了很多语言。但是上述这些编译器的致命缺陷是,他们是一个完整的可执行文件,没有给其它语言的开发者提供代码重用的接口。即使GCC是开源的,但是源代码重用的难度也比较大。
LLVM: Low Level Virtual Machine
LLVM最初是[Low Level Virtual Machine]的缩写,定位是一个虚拟机,但是是比较底层的虚拟机。它的出现正是为了解决编译器代码重用的问题,LLVM一上来就站在比较高的角度,制定了LLVM IR这一中间代码表示语言。LLVM IR充分考虑了各种应用场景,例如在IDE中调用LLVM进行实时的代码语法检查,对静态语言、动态语言的编译、优化等。
LLVM与GCC在三段式架构上并没有本质区别。LLVM与其它编译器最大的差别是,它不仅仅是Compiler Collection,也是Libraries Collection。举个例子,假如说我要写一个XYZ语言的优化器,我自己实现了PassXYZ算法,用以处理XYZ语言与其它语言差别最大的地方。而LLVM优化器提供的PassA和PassB算法则提供了XYZ语言与其它语言共性的优化算法。那么我可以选择XYZ优化器在链接的时候把LLVM提供的算法链接进来。LLVM不仅仅是编译器,也是一个SDK。

4. LLVM每日谈之一 LLVM是什么

写在前面的话: 最近接触llvm比较多,在这个上面花了不少的时间。感觉llvm要完全理解透是个很不容易的事情,需要在学习过程中好好的整理下自己的思路。刚好又阅读了开源项目Storm的作者Nathan Marz的博客《You should blog even if you have no readers》,就打开自己的blog,开始了这个llvm每日谈的系列。希望自己能坚持的久一点,多写写llvm的每个方面,多写写自己的理解。 llvm是low level virtual machine的简称,其实是一个编译器框架。llvm随着这个项目的不断的发展,已经无法完全的代表这个项目了,只是这种叫法一直延续下来。 llvm是一个开源的项目。它最早的时候是Illinois的一个研究项目,主要负责人是Chris Lattner,他现在就职于Apple. Apple 目前也是llvm项目的主要赞助者之一。 llvm的主要作用是它可以作为多种语言的后端,它可以提供可编程语言无关的优化和针对很多种CPU的代码生成功能。此外llvm目前已经不仅仅是个编程框架,它目前还包含了很多的子项目,比如最具盛名的clang. llvm的优点是开源,有一个表达形式很好的IR语言,模块化作的特别好。 llvm这个框架目前已经有基于这个框架的大量的工具可以使用。 llvm的官方网站地址是:llvm.org。在这里可以下载最新的发布代码,也可以找到介绍llvm的相关文档。 附录:llvm目前支持的工具(描述来自网络) llvm-as 将人类可读的 .ll 文件汇编成字节代码 llvm-dis 将字节代码文件反编成人类可读的 .ll 文件 opt 在一个字节代码文件上运行一系列的 LLVM 到 LLVM 的优化 llc 为一个字节代码文件生成本机器代码 lli 直接运行使用 JIT 编译器或者解释器编译成字节代码的程序 llvm-link 将几个字节代码文件连接成一个 llvm-ar 打包字节代码文件 llvm-ranlib 为 llvm-ar 打包的文件创建索引 llvm-nm 在 字节代码文件中打印名字和符号类型 llvm-prof 将 'llvmprof.out' raw 数据格式化成人类可读的报告 llvm-ld 带有可装载的运行时优化支持的通用目标连接器 llvm-config 打印出配置时 LLVM 编译选项、库、等等 llvmc 一个通用的可定制的编译器驱动 llvm-diff 比较两个模块的结构 bugpoint 自动案例测试减速器 llvm-extract 从 LLVM 字节代码文件中解压出一个函数 llvm-bcanalyzer 字节代码分析器 (分析二进制编码本身,而不是它代表的程序) FileCheck 灵活的文件验证器,广泛的被测试工具利用 tblgen 目标描述阅读器和生成器 lit LLVM 集成测试器,用于运行测试

5. Impala中 LLVM 的交叉编译、调用过程

[TOC]

Impala 使用的 LLVM JIT,首先通过 Clang 将源码编译成了 LLVM IR 文件,然后通过脚本将 IR 文件装成可加载的二进制文件,BE 进程在运行过程中,通过 LLVM 的加载接口,把二进制文件加载进来使用。

待编译的文件通过codegen/ impala-ir.cpp 指定

impala-ir.cpp 文件主要的作用就是把需要产生 LLVM IR 的文件包含进来。
确定了哪些文件需要产生 LLVM IR 之后,就开始生成 IR 的二进制文件了。大致流程如下:

这个阶段生成最初始的bc文件,使用的是 CLang 的编译工具。命令可见codegen/CMakeFiles.txt

生成的结果是 impala-sse-tmp.bc 文件。

使用LLVM 优化工具,对原始的 bc 文件进行优化。命令可见codegen/CMakeFiles.txt

生成的结果就是impala-sse.bc。

这一步使用的是Impala 自定义的一个脚本 file2array.sh ,将优化后的 bc 文件转换为可加载的二进制c 文件。命令可见codegen/CMakeFiles.txt。

生成的结果是impala-sse-ir.cc。这个文件内部就是用一个数组存放二进制的值。

be 进程就是通过读取 impala_sse_llvm_ir 数组,把 LLVM IR加载到进程中。
file2array.sh 脚本其实就是使用 xxd -i < impala-sse-ir.cc 命令把bc 文件内容转成 c 语言的二进制形式。

LlvmCodeGen 类通过 CreateImpalaCodegen 接口实例化 codegen 对象。 CreateImpalaCodegen 最终会调用 CreateFromMemory ,在 CreateFromMemory 中就是将上文中生成的 impala_sse_llvm_ir 数组通过 LLVM 接口加载进来。

完成加载后,就可以通过 GetFunction 获取指定的 IR 函数了。

所有的函数名及描述,定义在 impala-ir-names.h 和 impala-ir-functions.h ,这两个文件是有对应关系的,都是通过gen_ir_descriptions.py生成。

impala-ir-names.h 定义了数组 FN_MAPPINGS ,存储函数名和枚举值的映射关系,如下:

impala-ir-functions.h定义了所有函数的枚举值,如下:

通过 GetFunction 获取函数的时候,因为有了 FN_MAPPINGS 存储的映射关系,可以通过传入枚举值或者字符串符号查找函数。

在 InitializeLlvm 方法中会使用 FN_MAPPINGS ,对加载的 llvm 函数进行校验。

6. 如何利用LLVM写一个编译器

LLVM有自己的教程,如果你只想做个玩具,那可以首先试着实现LLVM Tutorial: Table of Contents的Kaleidoscope。深入的,请看他的文档http://llvm.org/docs/

Kaleidoscope是一个范式简单的脚本语言,教程里的词法,语法分析都是手写的,基本流程就是词法语法解析,利用LLVM的API生成中间代码并执行。

我用visual studio编译的LLVM(version 3.6)实现过Kaleidoscope,我遇到的坑不少,如果你想以visual studio编译的LLVM实现Kaleidoscope,你可能同样会遇到

1. LLVM的生成目标对象为ELF格式,在windows下使用JIT的API时会出现incompatible object format的错误警告,需要在通过重新设定Mole的triple,我的PC的getTargetTriple的结果是“i686-pc-windows-msvc”,直接在后面再加上“-elf”即可

TheMole->setTargetTriple("i686-pc-windows-msvc-elf");

2. LLVM不支持windows下通过动态链接导出函数,如果需要使用C/C++的函数,需要通过addSymbol进行注册

llvm::sys::DynamicLibrary::AddSymbol(/*std::string("_") +*/ "printd", &printd);

3. Kaleidoscope里使用的JIT的查找函数的API,getPointerToFunction已经被弃用了,需要替换为getFunctionAddress

7. Go语言编译器TinyGo,基于LLVM,在微控制器和小系统上编译和运行

TinyGo是一个为微控制器、WebAssembly(Wasm)和命令行工具等小型场景设计的Go语言编译器。TinyGo重用了Go语言工具和LLVM使用的库,以编译用Go语言编写的程序。目前,该项目在GitHub上已经积累了10.1k的Star。

如下为一个示例程序,当运行在任何支持的带板载LED的主板上时,则会点亮内置LED。

上述程序可以在单片机、Adafruit ItsyBitsy M0微控制器或任何支持的带内置LED的板上进行编译和不需要修改的运行,只要设置正确的TinyGo编译器目标即可。例如,设置如下目标可以编译和点亮 单片机。

项目概述

TinyGo项目旨在将Go语言引入到具有单进程或核心的微控制器和小系统。TinyGo类似于emgo,但主要的区别在于作者想要保留Go内存模型。另一个区别在于TinyGo在内部使用LLVM,因而可以获得更小更高效的代码以及更高的灵活性。

创建TinyGo项目的初衷是,如果Python可以在微控制器上运行,Go语言当然也应该能够在更低级微设备上运行。

支持设备

你可以为微控制器、WebAssembly和Linux编译TinyGo程序。目前,TinyGo支持以下85种微处理器板。

更多技术细节请参阅原项目。

8. 如何将Java bytecode编译成LLVM IR,即有没有可用的LLVM的Java前端

首先简要介绍一下LLVM。LLVM是一个针对LLVM Intermediate Representation(IR,中间语言)的跨平台优化编译器,它的模块化设计很好,使得这个编译器中的很多功能可以被单独实现或者改进,这与其C++实现无法分开。由此,LLVM可以被设计成很多语言

9. llvm 利用g++编译程序,此程序inclue了llvm的一些头文件。编译时出现 undefined reference to错误

你是要编译llvm和你自己在llvm上做的工程?llvm能用gnu工具链编译的,你的配置有问题,编译,链接脚本的顺序有问题。这跟是不是第三方库没关系

阅读全文

与编译llvm依赖相关的资料

热点内容
xlsx转换pdf 浏览:94
3dmax挤出命令英语 浏览:903
靶心率的定义和算法 浏览:513
3d模术师app哪里下载 浏览:474
php中文api文档 浏览:458
安卓设计怎么加入输入框 浏览:185
主根服务器什么时候开始 浏览:738
奇门遁甲完整版pdf 浏览:901
app软件怎么用的 浏览:802
电子书pdf购买 浏览:193
浪潮服务器如何做系统 浏览:111
冒险岛img格式加密 浏览:596
我的世界手游如何复制命令 浏览:659
天刀自动弹琴脚本源码 浏览:970
打开其它app微信怎么收不到 浏览:447
安卓游戏耳机怎么戴 浏览:18
不越狱怎么去除app广告 浏览:178
ipadminipdf阅读 浏览:507
文件夹无限制压缩会不会降低内存 浏览:412
荣耀怎样创建文件夹 浏览:631