type
status
date
slug
summary
tags
category
icon
password
📌
编译原理第一周作业。

源头-GCC和GDB

GCC与Apple

要想说clang的历史,就必须要提一下在此之前的独一档编译器GCC了。「GCC」(GNU Compiler Collection,GNU编译器套装)是一个非常强大的编译器,也是是GNU项目的关键部分。gcc被移植到各种操作系统中,其中就包括Mac OS X操作系统,并且成为了其标准的编译器。其中Mac OS X包含了自家软件的开发程序,其重大的特色是名为Xcode的集成开发环境,Xcode是一个能与各种编译器沟通的接口,而早期的Xcode中使用的编译器就是GCC。当时一同被移植进入Mac OS X的还有GNU软件系统中的标准调试器「GDB」(GNU Debugger),GDB可以配合GCC作为其调试除错的工具。
📝
GNU计划:GNU project,又译作革奴计划,是一个自由软件集体协议计划,他们的目标是创建一套完全自由的操作系统,称为GNU。「GNU」是GNU‘s Not Unix的递归缩写,其内容软件完全以GPL方式发布。 Mac OS X:Mac OS X 是与先前的 Mac OS 彻底地分离开来的一个操作系统,它的底层代码与先前版本完全不同。这个新的核心名为 Darwin,是一套开放源码、符合 POSIX 标准的操作系统,伴随着标准的 Unix 命令行与其强大的应用工具。

Apple对GCC的不满

虽然苹果公司在很长一段时间一直使用GCC作为其标准的编译器,但随着Apple对Object-C语言以及C语言新增了许多特性,当时的GCC开发者并不买Apple的账,也就是说并没有顺着Apple的意思实现,后期索性双方开了两条分支分别开发,这就导致Apple的编译器版本远远落后于官方版本,加之GCC许多历史遗留问题,导致代码耦合度过高、难以独立,越开发到后期代码质量就越差,基于这两个主要原因,Apple萌生了寻找一个高效、模块化、协议更放松的开源代替品,Chris Lattner的LLVM显然是一个很好的选择。

编译大神Chris Lattner

2000年,本科毕业的Chris Lattner就像大部分中国学生一样,参加了研究生入学考试,并成功考入了伊利诺伊大学厄巴纳-香槟分校(UIUC)。在此期间,他经年累月的学习《Compiler:Principles,Techniques,and Tools》这本龙书,当然刻苦学习的结果就是成了GPA满绩的牛人,并不断探索关于编译器的未知领域,发表了一篇又一篇的论文。在他的硕士毕业论文中,他提出了一套完整的在编译时、链接时、运行时甚至在闲置时优化程序的编译思想,这也直接奠定了LLVM的基础。LLVM在他博士期间更加成熟,此时的LLVM是分析用GCC做前端进行语义分析得到的intermediate format, 然后完成代码优化和生成。这个研究在他博士毕业时就成了业界小有名气的编译器专家,也因此被Apple早早盯上,于是Apple成了LLVM项目的主要资助者。

LLVM横空出世

定义

「LLVM」是一套编译器基础设施项目,为自由软件,以C++写成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。它是为了任意一种编程语言而写成的程序,利用虚拟技术创造出编译时期、链接时期、执行时期以及“闲置时期”的优化。
LLVM的命名最早来源于底层虚拟机(Low Level Virtual Machine)的首字母缩写,由于这个项目的范围并不局限于创建一个虚拟机,这个缩写也导致了许多误会。LLVM开始成长之后,成为了许多编译工具以及低端工具的统称,由于这个名字变得不在贴切,于是开发者便放弃了这个缩写的含义,现如今LLVM单纯成为了一个名牌,适用于LLVM下的所有项目,包含LLVM的调试工具,LLVM C++标准库函数等等。

LLVM的三段式架构

LLVM的不同之处在于,可以作为多种前端编译器的优化器,并且可以针对多种CPU架构生成对应的机器代码。其优势就是优化器的功能可重用,适用于多种编程语言和多种CPU架构平台。如下图所示:
notion image
这种三段式架构的优势是非常明显的:
  • 可重用:由于前后端是分离的,当需要移植一个新语言源时,只需要实现一个新的前端,而现有的优化器和后端可以直接重用。
  • 模块化:不同于其他编译器(如:GCC)的整体式设计,LLVM将各个阶段的编译技术模块化,尤其是语言无关的通用优化器,可支持多种语言输入,可输出多种架构的机器代码。
  • 丰富的开发者资源:这种设计意味着它支持不止一种源语言和目标平台(如:x86、ARM、MIPS),会吸引更多的开发人员参与到该项目中,就会有更多高质量的代码产生,这自然会对编译器带来更多的增强和改进。
  • 有利于分工:实现前端所需的技能与优化器、后端所需的技能不同,将它们分开可以使“前端人员”更容易地增强和维护他们的编译器部分。”后端人员“可以专注于中间代码的优化和目标平台机器代码的生成。

发展

LLVM最初被用来取代GCC中的代码产生器,而LLVM真正的发迹,则得等到 Mac OS X 10.6 Snow Leopard 登上舞台。可以说, Snow Leopard的新功能,完全得益于LLVM的技术。而这一个版本,也是将LLVM推向真正成熟的重大机遇。Snow Leopard的三项主推技术64位支持、OpenCL以及Grand Central Dispatch (GCD) ,GCD并随后被引入到了iOS 4.0中。而这些需求得以实现,归功于LLVM自身的新前端 — Clang。

Clang

Apple吸收Chris Lattner的目的要比改进GCC代码更具野心——Apple打算从零开始写 C、C++、Objective-C语言的前端编译器,完全替代掉GCC。
这个编译器就是Clang,”Clang: a C language family frontend for LLVM“,Clang 是一个只支持C、C++、Objective-C和Objective-C++四种C家族编程语言的编译器前端,它的设计目标就是上述所说的:GCC的代替品,这正是苹果当时所需要的。
现在的Xcode已经完全使用LLVM+Clang作为编译器了,只有LLVM时,编译器的前端是GCC,Clang开发出来以后,编译器的前端成了Clang,GCC在Xcode中不复存在。
Clang的加入让LLVM走向成熟和全能,苹果的开发面也焕然一新,从此摆脱了GCC的限制了,掌握了“核心科技”。而Chris Lattner以影响他最大的龙书封面为灵感,为项目选定了图标——一条张牙舞爪的飞龙。
notion image
 

新的时代到来

至此,Apple从GCC过渡到LLVM时代正式完成,GCC在Xcode中也正式落下了帷幕。

Clang与GCC相比的优势与局限性

优势

  • 编译速度快:在特定平台上,Clang 的编译速度显著的快过 GCC。
  • 占用内存小:Clang 生成的 AST 所占用的内存是 GCC 的五分之一左右。
  • 模块化设计:Clang 采用基于库的模块化设计,易于 IDE 集成及其他用途的重用。
  • 诊断信息可读性强:在编译过程中,Clang 创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告,例如Xcode中对错误精确的标红提示,以及给出快捷修复建议等。
  • 设计清晰简单:容易理解,易于扩展增强,与代码基础古老的 GCC 相比,学习曲线平缓。

局限性

当前 Clang 还处在不断完善过程中,相比于 GCC, Clang 在以下方面还需要加强:
  • 支持更多语言:GCC 除了支持 C/C++/Objective-C, 还支持 Fortran/Pascal/Java/Ada/Go 和其他语言。Clang 目前支持的语言有 C/C++/Objective-C/Objective-C++。
  • 加强对 C++ 的支持:Clang 对 C++ 的支持依然落后于 GCC,Clang 还需要加强对 C++ 提供全方位支持。
  • 支持更多平台:GCC 流行的时间比较长,已经被广泛使用,对各种平台的支持也很完备。Clang 目前支持的平台有 Linux/Windows/Mac OS。

📎 参考链接

泵引理讨论软工第六周会议记录