您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

详解三大编译器:gcc、llvm 和 clang

时间:2020-11-03 10:18:35  来源:  作者:

编译器一般构成

传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd)。在编译过程中,前端主要负责词法和语法分析,将源代码转化为抽象语法树;优化器则是在前端的基础上,对得到的中间代码进行优化,使代码更加高效;后端则是将已经优化的中间代码转化为针对各自平台的机器代码。

GCC

GCC(GNU Compiler Collection,GNU编译器套装),是一套由 GNU 开发的编程语言编译器。GCC 原名为 GNU C 语言编译器,因为它原本只能处理 C语言。GCC 快速演进,变得可处理 C++、Fortran、Pascal、Objective-C、JAVA, 以及 Ada 等他语言。

详解三大编译器:gcc、llvm 和 clang
 
 
 

LLVM

LLVM (Low Level Virtual machine,底层虚拟机) 提供了与编译器相关的支持,能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。简而言之,可以作为多种编译器的后台来使用。

苹果公司一直使用 GCC 作为官方的编译器。GCC 作为一款开源的编译器,一直做得不错,但 Apple 对编译工具会提出更高的要求。原因主要有以下两点:

其一,是 Apple 对 Objective-C 语言(包括后来对C语言)新增很多特性,但 GCC 开发者并不买Apple的账——不给实现,因此索性后来两者分成两条分支分别开发,这也造成 Apple 的编译器版本远落后于 GCC 的官方版本。其二,GCC 的代码耦合度太高,很难独立,而且越是后期的版本,代码质量越差,但 Apple 想做的很多功能(比如更好的 IDE 支持),需要模块化的方式来调用 GCC,但 GCC一直不给做。

编译器大神 Chris Lattner 横空出世

2000年,本科毕业的 Chris Lattner 像中国多数大学生一样,按部就班地考了GRE,最终前往UIUC(伊利诺伊大学厄巴纳香槟分校),开始了艰苦读计算机硕士和博士的生涯。在这阶段,他不仅周游美国各大景点,更是翻烂了《Compilers: Principles, Techniques, and Tools》,成了GPA满分(4.0) 牛人,并不断地研究探索关于编译器的未知领域,发表了一篇又一篇的论文,。他在硕士毕业论文里提出了一套完整的在编译时、链接时、运行时甚至是在闲置时优化程序的编译思想,直接奠定了LLVM 的基础。LLVM 在他念博士时更加成熟,使用GCC 作为前端来对用户程序进行语义分析产生IF(Intermidiate Format),然后 LLVM 使用分析结果完成代码优化和生成。这项研究让他在2005年毕业时就成为了业界小有名气的编译器专家,他也因此早早地被Apple 盯上,最终成为其编译器项目的骨干。

刚进入 Apple,Chris Lattner 就大展身手:首先在 OpenGL 小组做代码优化,把 LLVM运行时的编译架在 OpenGL 栈上,这样OpenGL 栈能够产出更高效率的图形代码。如果显卡足够高级,这些代码会直接扔入GPU 执行。但对于一些不支持全部OpenGL特性的显卡(比如当时的Intel GMA卡),LLVM 则能够把这些指令优化成高效的 CPU指令,使程序依然能够正常运行。这个强大的 OpenGL 实现被用在了后来发布的Mac OS X 10.5上。同时,LLVM的链接优化被直接加入到 Apple 的代码链接器上,而 LLVM-GCC也被同步到使用 GCC4.0 代码。

详解三大编译器:gcc、llvm 和 clang
 
 
 

LLVM2.0 - Clang

Apple 吸收Chris Lattner的目的要比改进GCC代码更具野心 -- Apple 打算从零开始写 C、C++、Objective-C语言的前端 Clang,完全替代掉GCC。

Clang 是LLVM的前端,可以用来编译C,C++,ObjectiveC等语言。Clang则是以LLVM为后端的一款高效易用,并且与IDE 结合很好的编译前端。

Clang 只支持C,C++和Objective-C三种语言。2007年开始开发,C编译器最早完成,而由于Objective-C 只是C语言的一个简单扩展,相对简单,很多情况下甚至可以等价地改写为C语言对Objective-C运行库的函数调用,因此在2009年时,已经完全可以用于生产环境。C++ 在后来也得到了支持。

详解三大编译器:gcc、llvm 和 clang
 
 
 

GCC 和 Clang 对比

  • Clang特性

速度快:通过编译 OS X 上几乎包含了所有 C 头文件的 carbon.h 的测试,包括预处理 (Preprocess),语法 (lex),解析 (parse),语义分析 (Semantic Analysis),抽象语法树生成 (Abstract Syntax Tree) 的时间,Clang 比 GCC 快2倍多。

内存占用小:Clang 内存占用是源码的 130%,Apple GCC 则超过 10 倍。

诊断信息可读性强:其中错误的语法不但有源码提示,还会在错误的调用和相关上下文的下方有~~~~~和^的提示,相比之下 GCC 的提示很天书。

兼容性好:Clang 从一开始就被设计为一个API,允许它被源代码分析工具和 IDE 集成。GCC 被构建成一个单一的静态编译器,这使得它非常难以被作为 API 并集成到其他工具中。

Clang有静态分析,GCC没有。

Clang使用BSD许可证,GCC使用GPL许可证。

详解三大编译器:gcc、llvm 和 clang
 
 
 
  • GCC 优势

支持 JAVA/ADA/FORTRAN

GCC 支持更多平台

GCC 更流行,广泛使用,支持完备

GCC 基于 C,不需要 C++ 编译器即可编译

GCC、LLVM 和 Clang 如何选择?

目前不推荐使用老的GCC4.2,因为苹果不会维持它了,而且LLVM-GCC看起来会更好。在项目中途改编译选项可是一个大变动,需要慎重。

对新的项目而言,LLVM-GCC 看起來应该是个安全的选择,苹果公司认为它够稳定够成熟,所以才把它当做Xcode 4的预设选项。而且,既然选项使用的是GCC parser,向后兼容性应该没问题。

LLVM-GCC是个安全的选项,但并不是指Clang/LLVM比较不安全,只是成熟度还沒那么高效了。

总结 - 再探LLVM

回顾GCC的历史,虽然它取得了巨大的成功,但开发GCC的初衷是提供一款免费的开源编译器,仅此而已。可后来随着GCC支持了越来越多的语言,GCC架构的问题也逐渐暴露出来。但GCC到底有什么问题呢?LLVM的优点也正是GCC的缺点。传统编译器工作的时候前端负责解析源代码,检查语法错误,并将其翻译为抽象的语法树(Abstract Syntax Tree)。优化器对这一中间代码进行优化,试图使代码更高效。后端则负责将优化器优化后的中间代码转换为目标机器的代码,这一过程后端会最大化的利用目标机器的特殊指令,以提高代码的性能。事实上,不光静态语言如此,动态语言也符合上面这个模型,例如Java。JVM也利用上面这个模型,将Java代码翻译为Java bytecode。这一模型的好处是,当我们要支持多种语言时,只需要添加多个前端就可以了。当需要支持多种目标机器时,只需要添加多个后端就可以了。对于中间的优化器,我们可以使用通用的中间代码。这种三段式的结构还有一个好处,开发前端的人只需要知道如何将源代码转换为优化器能够理解的中间代码就可以了,他不需要知道优化器的工作原理,也不需要了解目标机器的知识。这大大降低了编译器的开发难度,使更多的开发人员可以参与进来。虽然这种三段式的编译器有很多优点,并且被写到了教科书上,但是在实际中这一结构却从来没有被完美实现过。做的比较好的应该属Java和.NET虚拟机。虚拟机可以将目标语言翻译为bytecode,所以理论上讲我们可以将任何语言翻译为bytecode,然后输入虚拟机中运行。但是这一动态语言的模型并不太适合C语言,所以硬将C语言翻译为bytecode并实现垃圾回收机制的效率是非常低的。GCC也将三段式做的比较好,并且实现了很多前端,支持了很多语言。但是上述这些编译器的致命缺陷是,他们是一个完整的可执行文件,没有给其它语言的开发者提供代码重用的接口。即使GCC是开源的,但是源代码重用的难度也比较大。

LLVM最初的定位是比较底层的虚拟机。它的出现正是为了解决编译器代码重用的问题,LLVM一上来就站在比较高的角度,制定了LLVM IR这一中间代码表示语言。LLVM IR充分考虑了各种应用场景,例如在IDE中调用LLVM进行实时的代码语法检查,对静态语言、动态语言的编译、优化等。从上面这个图中我们发现LLVM与GCC在三段式架构上并没有本质区别。LLVM与其它编译器最大的差别是,它不仅仅是Compiler Collection,也是Libraries Collection。举个例子,假如说我要写一个X语言的优化器,我自己实现了PassX算法,用以处理X语言与其它语言差别最大的地方。而LLVM优化器提供的PassA和PassB算法则提供了X语言与其它语言共性的优化算法。那么我可以选择X优化器在链接的时候把LLVM提供的算法链接进来。LLVM不仅仅是编译器,也是一个SDK。Apple LLVM compiler 4.2是一个真正的LLVM编译器,前端使用的是Clang,基于最新的LLVM 3.2编译的。LLVM GCC 4.2编译器的核心仍然是LLVM,但是前端使用的是GCC 4.2编译器。从LLVM的下载页面可以看出,LLVM从1.0到2.5使用的都是GCC作为前端,直到2.6开始才提供了Clang前端。

如果你下载 LLVM 的代码,那么它就是一个IR到ARM/机器码的编译器。比如bin/opt就是对IR的优化器,bin/llc就是IR->ASM的翻译,bin/llvm-mc就是汇编器。如果你再从http://llvm.org下载Clang,那么就有了C->IR的翻译以及完整的编译器Driver。GDB是GNU的调试器。只要编译器支持DWARF格式,就可以用GDB调试。



Tags:编译器   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
C语言作为高级语言,用其编写的程序指令机器并不能识别,因此需要有一个编译器将其转换为机器可识别的二进制指令。C语言已经出现50多年的时间,其相关的编译器种类众多,从最早先的...【详细内容】
2021-08-24  Tags: 编译器  点击:(130)  评论:(0)  加入收藏
仅就从性能部分的错误诊断比较区别,之前见国外有相关文章,我做简单分享,但是,如果要了解区别,无妨从下文中包含的gcc和msvc阅读了解一下。GCC和Clang一直在彼此较劲尝试证明谁的...【详细内容】
2021-03-22  Tags: 编译器  点击:(617)  评论:(0)  加入收藏
编译器一般构成传统的编译器通常分为三个部分,前端(frontEnd),优化器(Optimizer)和后端(backEnd)。在编译过程中,前端主要负责词法和语法分析,将源代码转化为抽象语法树;优化器则...【详细内容】
2020-11-03  Tags: 编译器  点击:(109)  评论:(0)  加入收藏
gcc编译器编译过程详解gcc常用选项 一个c/c++文件要经过预处理、编译、汇编和链接才能变成可执行文件。 (1)预处理 C/C++源文件中,以#开头的命令被称为预处理命令,如包含命令#in...【详细内容】
2020-07-30  Tags: 编译器  点击:(51)  评论:(0)  加入收藏
简单介绍一下编程方式的历史演变。-- Erik O'shaughnessy(作者)在计算机诞生不久的早期年代,硬件非常昂贵,而程序员比较廉价。这些廉价程序员甚至都没有“程序员”这个头衔...【详细内容】
2020-06-26  Tags: 编译器  点击:(70)  评论:(0)  加入收藏
原作:Archie Mistry翻译:豌豆花下猫@Python猫原文:https://morioh.com/p/765b19f066a4Python 是一门对初学者友好的编程语言,是一种多用途的、解释性的和面向对象的高级语言。它...【详细内容】
2020-01-10  Tags: 编译器  点击:(27)  评论:(0)  加入收藏
各位,关于编译器和集成开发环境这两个名称,我们平时一直在说,但这二位究竟有什么区别和联系呢,今天就跟大家简单聊一聊。 我们平时所说的程序,是指双击后就可以直接运行的程序,这...【详细内容】
2019-11-11  Tags: 编译器  点击:(102)  评论:(0)  加入收藏
我们平时所说的程序,是指双击后就可以直接运行的程序,这样的程序被称为可执行程序(Executable Program)。在 Windows 下,可执行程序的后缀有 .exe 和 .com(其中 .exe 比较常见);在类...【详细内容】
2019-10-12  Tags: 编译器  点击:(135)  评论:(0)  加入收藏
华为方舟编译器终于正式开源,源代码放出,兑现了在8月开源的承诺。...【详细内容】
2019-09-02  Tags: 编译器  点击:(356)  评论:(0)  加入收藏
今日华为EMUI官方微信发文宣布,方舟编译器开源准备就绪,将于8月31日起开源。方舟编译器是完全替代了语言虚拟机的静态编译器,从此不再需要解释器。相比现有的编译机制有以下明...【详细内容】
2019-08-30  Tags: 编译器  点击:(200)  评论:(0)  加入收藏
▌简易百科推荐
摘 要 (OF作品展示)OF之前介绍了用python实现数据可视化、数据分析及一些小项目,但基本都是后端的知识。想要做一个好看的可视化大屏,我们还要学一些前端的知识(vue),网上有很多比...【详细内容】
2021-12-27  项目与数据管理    Tags:Vue   点击:(1)  评论:(0)  加入收藏
程序是如何被执行的  程序是如何被执行的?许多开发者可能也没法回答这个问题,大多数人更注重的是如何编写程序,却不会太注意编写好的程序是如何被运行,这并不是一个好...【详细内容】
2021-12-23  IT学习日记    Tags:程序   点击:(9)  评论:(0)  加入收藏
阅读收获✔️1. 了解单点登录实现原理✔️2. 掌握快速使用xxl-sso接入单点登录功能一、早期的多系统登录解决方案 单系统登录解决方案的核心是cookie,cookie携带会话id在浏览器...【详细内容】
2021-12-23  程序yuan    Tags:单点登录(   点击:(8)  评论:(0)  加入收藏
下载Eclipse RCP IDE如果你电脑上还没有安装Eclipse,那么请到这里下载对应版本的软件进行安装。具体的安装步骤就不在这赘述了。创建第一个标准Eclipse RCP应用(总共分为六步)1...【详细内容】
2021-12-22  阿福ChrisYuan    Tags:RCP应用   点击:(7)  评论:(0)  加入收藏
今天想简单聊一聊 Token 的 Value Capture,就是币的价值问题。首先说明啊,这个话题包含的内容非常之光,Token 的经济学设计也可以包含诸多问题,所以几乎不可能把这个问题说的清...【详细内容】
2021-12-21  唐少华TSH    Tags:Token   点击:(9)  评论:(0)  加入收藏
实现效果:假如有10条数据,分组展示,默认在当前页面展示4个,点击换一批,从第5个开始继续展示,到最后一组,再重新返回到第一组 data() { return { qList: [], //处理后...【详细内容】
2021-12-17  Mason程    Tags:VUE   点击:(14)  评论:(0)  加入收藏
什么是性能调优?(what) 为什么需要性能调优?(why) 什么时候需要性能调优?(when) 什么地方需要性能调优?(where) 什么时候来进行性能调优?(who) 怎么样进行性能调优?(How) 硬件配...【详细内容】
2021-12-16  软件测试小p    Tags:性能调优   点击:(19)  评论:(0)  加入收藏
Tasker 是一款适用于 Android 设备的高级自动化应用,它可以通过脚本让重复性的操作自动运行,提高效率。 不知道从哪里听说的抖音 app 会导致 OLED 屏幕烧屏。于是就现学现卖,自...【详细内容】
2021-12-15  ITBang    Tags:抖音防烧屏   点击:(23)  评论:(0)  加入收藏
11 月 23 日,Rust Moderation Team(审核团队)在 GitHub 上发布了辞职公告,即刻生效。根据公告,审核团队集体辞职是为了抗议 Rust 核心团队(Core team)在执行社区行为准则和标准上...【详细内容】
2021-12-15  InfoQ    Tags:Rust   点击:(24)  评论:(0)  加入收藏
一个项目的大部分API,测试用例在参数和参数值等信息会有很多相似的地方。我们可以复制API,复制用例来快速生成,然后做细微调整既可以满足我们的测试需求1.复制API:在菜单发布单...【详细内容】
2021-12-14  AutoMeter    Tags:AutoMeter   点击:(20)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条