现在的位置: 首页 > 综合 > 正文

编译器Clang介绍

2013年09月15日 ⁄ 综合 ⁄ 共 7616字 ⁄ 字号 评论关闭

LLVM 与 Clang 介绍

{ 撰文/guest }
来源:http://linuxtoy.org/archives/llvm-and-clang.html

 

LLVM 是 Low Level Virtual Machine 的简称,这个库提供了与编译器相关的支持,能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。简而言之,可以作为多种语言编译器的后台来使用。如果这样还比较抽象的话,介绍下 Clang 就知道了:Clang
是一个 C++ 编写、基于 LLVM、发布于 LLVM BSD 许可证下的 C/C++/Objective C/Objective C++ 编译器,其目标(之一)就是超越 GCC。

Clang 开发事出有因,Wiki 介绍如下:

Apple 使用 LLVM 在不支持全部 OpenGL 特性的 GPU (Intel 低端显卡) 上生成代码 (JIT),令程序仍然能够正常运行。之后 LLVM 与 GCC 的集成过程引发了一些不快,GCC 系统庞大而笨重,而 Apple 大量使用的 Objective-C 在 GCC 中优先级很低。此外 GCC 作为一个纯粹的编译系统,与 IDE 配合很差。加之许可证方面的要求,Apple 无法使用修改版的 GCC 而闭源。于是 Apple 决定从零开始写 C family 的前端,也就是基于 LLVM 的
Clang 了。

Clang 的特性:

  1. 快:通过编译 OS X 上几乎包含了所有 C 头文件的 carbon.h 的测试,包括预处理 (Preprocess),语法 (lex),解析 (parse),语义分析 (Semantic Analysis),抽象语法树生成 (Abstract Syntax Tree) 的时间,Clang 是 Apple GCC 4.0 的 2.5x 快。(2007-7-25)
  2. 内存占用小:Clang 内存占用是源码的 130%,Apple GCC 则超过 10x。
  3. 诊断信息可读性强:我不会排版,推荐去网站观看。其中错误的语法不但有源码提示,还会在错误的调用和相关上下文的下方有~~~~~和^的提示,相比之下 GCC 的提示很天书。
  4. GCC 兼容性。
  5. 设计清晰简单,容易理解,易于扩展增强。与代码基础古老的 GCC 相比,学习曲线平缓。
  6. 基于库的模块化设计,易于 IDE 集成及其他用途的重用。由于历史原因,GCC 是一个单一的可执行程序编译器,其内部完成了从预处理到最后代码生成的全部过程,中间诸多信息都无法被其他程序重用。Clang 将编译过程分成彼此分离的几个阶段,AST 信息可序列化。通过库的支持,程序能够获取到 AST 级别的信息,将大大增强对于代码的操控能力。对于 IDE 而言,代码补全、重构是重要的功能,然而如果没有底层的支持,只使用 tags 分析或是正则表达式匹配是很难达成的。

当然,GCC 也有其优势:

相信介绍到这里大家能够对 Clang 和 LLVM 有所了解了。除去 Clang 之外,LLVM 还被用在 Gallium3D 中进行 JIT 优化,Xorg 中的 pixman 也有考虑使用 LLVM 来优化执行速度,llvm-lua 使用
LLVM 来编译 Lua 代码,gpuocelot 使用 LLVM 可以令 CUDA 程序无需重新编译即可运行在多核 X86CPU、IBM Cell、支持 OpenCL 的设备之上... 我个人感觉 Apple 在开源界口碑较差(也许是我的错觉?),不过
Apple 也为开源界贡献了不少,Webkit,OpenCL(虽说只是个标准),Clang。我最为佩服的是虽然出身于命令行之上的 Unix 族系统,但有魄力写出自成体系的图形栈,其图形界面优美而人性化,可谓也为开源界贡献了自己的精神与思想。对于 Clang 这个很有潜力的项目,我希望其 C++ 支持(尤其是 template 支持)能够早日完善。因为 GCC 在 template 出错时的诊断信息如同小说一般...

{ Thanks guest. }

 

 

 

雪豹的心脏:LLVM和Clang

来源:http://news.weiphone.com/news/apple/blog/2009-09-27/xuebaodexinzangLLVMheClang_206356.shtml

 

     Mac OS X 10.6即所谓的Snow Leopard操作系统已正式发售。一如既往,Apple产品光鲜的外表下凝聚了太多艰辛的劳作。ArsTechnic的John Siracusa以其独特的、专业的、全面的视角深入翔实地体验这款最新的操作系统。   

      Weiphone.com将对该综述进行翻译整理并独家连载。欢迎关注。


译注:为了帮助您更加顺畅地理解本文的内容,这里补充了文中一些相关概念的背景资料。

      编译器(compiler):是一种能够将源代码(通常由高级别的程序语言编写而成)转换为低级别机器语言的程序。源码转换最重要的一个目的在于创建可执行文件。详情请参考wikipedia

      LLVM(Low Level Virtual Machine,低级虚拟机):是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。LLVM计划启动于2000年,最初由University
of Illinois at Urbana-Champaign的Chris Lattner主持开展。2006年Chris Lattner加盟Apple Inc.并致力于LLVM在Apple开发体系中的应用。Apple也是LLVM计划的主要资助者。详情请参考llvm.org以及wikipedia

      GCC(GNU Compiler Collection,缩写为GCC):是GNU计划推出的支持多种程序语言的编译器系统。GCC是GNU Toolchain的主要组件。同时作为GNU操作系统的官方编译器,GCC已被作为很多现代操作系统的标准编译器,如GNU/Linux,BSD以及Mac OS X;同时也可用于很多嵌入式平台,如Symbian,AMCC等;还可用于一些游戏机平台如Playstation和Sega
Dreamcast等。详情请参阅Wikipedia以及GCC.GNU.org

      IDE(Integrated development environment):是一种能够为程序员和软件开发提供广泛支持的软件程序。IDE通常由源码编辑器、编译器、自动化构建工具以及调试器组成。详情请参阅Wikipedia

 

      早在几年以前,Apple就在LLVM开源计划上做出了重要的战略性投资。我曾在一篇介绍Mac OS X Leopard的文章中简要介绍了LLVM的一些基本情况,Leopard利用LLVM技术为JIT编译软件的OpenGL功能提供了高效的执行支持。在那篇综述的最后,我这样结尾:对于LLVM,Apple拥有相当宏伟的计划:逐步摒弃Mac OS X中现有的GCC编译器集合(complier collection),并采用全新的基于LLVM的编译器系统。该计划称为"Clang",并且已有了一些可喜的进展。        
 
      随着Snow Leopard的推出,这一切开始逐渐浮出水面:Clang和LLVM已成为Apple现行的编译策略。LLVM甚至还有一个全新的帅气的标志:

 

      目前,Apple为Mac OS X总共提供了四种编译器:GCC 4.0,GCC4.2,LLVM-GCC 4.2,以及Clang。这里是一个图表:

 

      所有这些编译器在Mac OS X上均具有二进制兼容性(binary-compatible),这就意味着您可以使用一种编译器创建一个资源库并与使用另一个编译器创建的可执行文件相链接。并且,理论上讲,这些都是命令行编辑器并且都具有资源兼容性。然而,Clang目前暂不支持GCC的一些复杂功能,同时Clang只支持C、Objective-C和一点点C++(而GCC支持的相对较多)。Apple承诺,Clang未来将会为C++提供全方位支持,并且希望能够在Snow Leopard的“服役期间”内解决GCC的不兼容问题。

      Apple为Clang带来了两条引人注目的特性,那就是:更短的编译时间和更快的可执行文件。Apple用其自身的软件如iCal,Address Book,Xcode,以及一些第三方软件如Adium和Growl进行了测试,Clang编译器比GCC4.2快了近乎3倍。而对于编译的可执行文件运行速度,由Clang生成的可执行文件则比GCC 4.2生成的可执行文件快5~25%。

      同时,与其前任GCC相比,Clang提供了更为友好的开发环境。我承认这和多核CPU等新技术的优势并无很大关联,但这确实开发者在使用Clang时首先面对的。

      对于新手来说,Clang具有可嵌入性,因此Xcode可以在IDE的一些交互功能中使用和最终的可执行文件相同的编译器结构。在编译过程中,Clang创建并保留了大量详细的元数据(metadata),从而有利于调试和错误报告。例如,如果GCC返回如下错误:

 

      这时候很难说清问题究竟在哪,对于编程新手来说尤为如此。好吧,牛人或许已经看出来问题在哪了(如果您在WWDC上看到了这个例子的话),但是我相信大家都会认为Clang返回的错误报告更有用:

 

       可能个别菜鸟仍然不知所措,但是至少可以清晰地看到问题究竟出在哪里了:与GCC含糊其辞的回应相比,Clang明明白白告诉你,哥们儿我不认识“NSString”这个类型… 

       而且,有时候即使错误信息很明确,具体细节却未必如此,譬如GCC返回的这个错误提示:

 

      很明显,“无效的运算符号+”,但是这条语句中有4个“+”,究竟哪一个有问题呢?多亏这些相近的元数据(metadata),Clang可以明确地为您指出问题所在:

 

      更进一步抬杠。有时候错误一目了然,譬如这个GCC的例子,在报错行以上的语句中丢失了一个分号“;”:

 

      而Clang则更进一步,指出了究竟哪里丢失了这个分号:

 

      楼下同学说了,这些都是“小事儿”,完全是鸡蛋里头挑骨头没事儿找事儿,然而对于程序员来说,Clang提供的这种更为细致和细心的提示是相当贴心的。当然,还有一些细节对于程序员来说则意义重大了,譬如这个基于LLVM的静态分析器(static analyzer)。下图显示了静态分析器发现并指出了一处可能的bug:

 

      图中高亮的部分明确地指出了任何一位程序员都有可能犯的bug。静态分析器检测到,这一系列嵌套条件中,“myName”变量在至少一条路径里中未被初始化,从而使得在最后一行发送“mutableCopy”时存在潜在的危险。

      我相信Apple一定在其所有应用程序和操作系统上运行过静态分析器,以检查一些潜在的bug。而对程序员来说,能够在庞大的代码库中自动监测潜在的bug,无疑是一件非常爽的事情,对于自己开发平台的程序员来说更是如此。某种程度上来讲,Mac OS X 10.6.0中存在的bug比先前的任何一个10.x.0系统的bug都要少,无疑这将归功于LLVM。

      通过Clang/LLVM的进一步推广和完善,Apple终于能够完全掌控其自己的开发平台了。CodeWarrior的经验显然使Apple更加清晰地认识到,依赖于第三方平台开发工具是相当不明智的。尽管花费了许多年的时间,但我认为即使最顽固的Metrowerks支持者也会认为,Snow Leopard提供的Xcode确实是个相当不错的IDE。

      许多年以来Apple一直纠结于GCC计划与Apple自身的编译需求之间的脱节,现在Apple终于痛下决心另辟蹊径。诚然,GCC 4.2仍然是Snow Leopard的默认编译器,但是很显然Apple已进入的过渡期。Clang自然是推荐的编译器,并且在可预见的将来,Apple的焦点将集中于此。

llvm/clang将把FreeBSD带向何方?
对于FreeBSD最近的发展,最引人注目、最让人有所期待、最让人遐想的就是在将来的某个版本里将引入llvm/clang。这是一个什么东西?为什么值得期待?请听我慢慢地扯。

llvm/clang是一个编译器,llvm是类似虚拟机的东西(www.llvm.org),这个虚拟机不是类似java或者说python的VM,llvm的目的不是运行而是编译生成代码。也就是说这个llvm是编译器的后端。clang呢,(clang.llvm.org)简单来说就是llvm一个C语言家族的前端,它的责任就是把C家族语言翻译成llvm认识的中间代码,然后再由llvm后端生成具体架构的汇编代码,最后由系统中的汇编器、连接器生成某一个架构下的可执行文件。

说实话,任何编译器不都是这个套路吗?分前端后端,代码生成,也许还有代码优化, llvm到底有什么不同?最主要的是llvm提供的是函数库,一组较好定义的接口,使得编译器前端的设计相当的傻瓜。我们可以为Perl写一个llvm的前端,它就可以把perl脚本编译成本地二进制代码运行;给python写个前端,它一样可以编译。不要以为这个前端有多么的复杂,通过llvm比较合理的接口,这个工作不是很难。

所以总得来说llvm/clang的架构要优于GCC的架构(其实写个GCC的语言前端也不是什么大事,但是你必须了解GCC内部的机制和细节,并不能像llvm那样调用几个库函数就把事情给搞定。),就因为这个优势,FreeBSD准备迁移到llvm/clang上面。怎么可能? 不要太天真了。一个庞大的操作系统要迁移到另外一个还在开发之中的编译器上,不是一件容易的事情。这么做的原因其实是GNU把后续开发的GCC变成GPLv3了,BSD的人本来就对GPL不感冒,这个V3影响到了使用FreeBSD做商业运作的公司的核心利益。其实如果使用FreeBSD的商业公司愿意对FreeBSD贡献一下力量的话(确实已经贡献了不少力量),llvm/clang不用多久就可以引入FreeBSD的base,而且llvm/clang本身还能有长足的发展。但是人嘛,总是只想得到不想付出的,商业公司做事的唯一考量就是做这件事情有没有利益。所以llvm/clang要真正实用不是近期的事情,虽然FreeBSD的svn中有了clangbsd这个项目。

有人也曾经提出一个Unix的source base里面只能有C语言写的程序,所以FreeBSD只需要PCC(http://pcc.ludd.ltu.se/)。PCC也是一个老壶装新酒的编译器,它是UNIX的research版本的编译器,后来有人重新修改、重写了一遍,变成一个经典的分2个pass的C编译器,并支持C99标准。这个没有能进入FreeBSD其实一方面是在目前的工业界是回避不了C++的(llvm/clang是使用C++写的,clang对C++的全面的支持是一定的,不然clang自己都不能bootstrap啊。),除非做个理想的操作系统如Plan9那样,设计的好不好,当然好,就是20多年还没有被大众接受。要让一个Unix系统中只用C语言就像让现在的中国走社会主义道路一样,好不好?当然好,就是现实做不到。第二个方面用PCC编译FreeBSD的事情没有人肯去做,我也在mailling
list上呼吁过,说什么可以使用PCC啊,多么经典啊,多么简单啊,自己就是不想去修改一个Makefile,不想去查看一行代码。嗨。。人嘛,就设个本性,牛都是要吹的,事情最好都人家做。(BTW:一直想修改FreeBSD的msdosfs让其支持UTF-8的中文文件名的,就是一直没做,其实是想等别人来做或者允许我找个借口--忙啊!!囧)

革命呢,还是要充满乐观主义情绪的,所以我相信llvm/clang最终会进入FreeBSD的base。那个时候我们刚装完FreeBSD后,第一个要干的事情是到ports中安装最新的gcc。因为大量的ports中的软件是非gcc不可编译的,当然有些简单的软件是可以用clang编的,比如shell/bash(我试过,编出来的可执行文件比gcc编出来的小,但是编译时间比gcc长,执行性能就不知道了)。

革命呢,也是要认清人民群众的本性的。如果想要在近年内完全脱离GNU编译器族,那也不太可能。llvm/clang就是个C/C++编译器,最后还要使用系统中的汇编器和连接器来生成可执行文件的,在FreeBSD中这些as和ld可都是GNU的。虽然BSD的binutils早就在开发了,除了有个ar,nm之类的东西开发完成,as,ld估计是八字没有一瞥呢。当然,我也理解啊,有的用就先用着,何必为了licence去重造轮子呢?对于assembler估计llvm项目自己会出一个,好像叫“mc”(也是听人家在mailling
list上吹的),至于linker嘛,虽说不是什么复杂的软件,估计要等GNU把它的ld变成GPLv3才有希望看到BSD的linker了。

最后,这个新的编译器将把FreeBSD带向哪里?也不能带向哪里(我承认我是个标题党。。。),不就是个编译器嘛,再说近期还不可能实用。倒是FreeBSD-8的新东西比较吸引人,新的TTY层、增强的kernel SMP、ULE、Gaint lock 进一步去除,特别是网络栈中Gaint lock的去除,我就等待着FB-8的性能测试报告,估计在多CPU的情况下,网络栈的性能要上个档次!还有新的USB代码(我没有觉得老代码有什么不好,新代码估计是架构上的改进,具体还没看。。),增加amd64上kernel内存的极限,这下使用ZFS更加啦风了。新的AHCI(SATA)driver,进入了CAM子系统,终于把SATA当作SCSI处理了,(是不是落后与Linux了?无所谓,稳定了的东西我们才用)。

等着FreeBSD-8吧,就在近期了。(要习惯于跳票哦,呵呵)

抱歉!评论已关闭.