🔧【Tools】编译器基础
gcc的历史
GNU 项目计划的主要目的是创建一个名叫 GNU’s Not Unix(GNU) 的完全免费的操作系统。该操作系统将包括绝大多数自由软件基金会所开发的其他软件,以对抗所有商业软件,而这个操作系统的核心(kernel)就叫 HURD。
但是 GNU 在开发完全免费的操作系统上并未取得成功,直到 20 世纪 90 年代由林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds)开发了Linux 操作系统,GNU 才算在免费操作系统上完成了任务。
虽然 GNU 计划在开发免费操作系统上不成功,但是却成功开发几个广为流传的 GNU 软件,其中最著名的是 GNU C Complier(gcc)。
这个软件成为历史上最优秀的C语言编辑器, 其执行效率与一般的编译器相比平均效率要高 20%~30%,使得那些靠贩卖编译器的公司大吃苦头,因为它们无法研制出与 gcc 同样优秀,却又完全免费、并开放源代码的编译器来。
而由于它又是 copylefted,所以一旦有用户发现错误,就会通知 Richard Stallman,所以几乎每个月都可以推出新版本。然而,它还有一个十分特殊而且不同寻常的意义:几乎所有的自由软件都是通过它编译的。可以说,它是自由软件发展的基石与标杆。
现在,gcc 已经可以支持 7 种编程语言和 30 种编程结构,是学术界最受欢迎的编译工具。
其他 GNU 软件还包括 GNU emacs、GNU Debugger(GDB)、GNU Bash 以及大部分 Linux 系统的程序库和工具等。
目前,gcc 已发展到了 8.x 的版本,几乎所有开源软件和自由软件中都会用到,因此它的编译性能会直接影响到 Linux、Firefox、OpenOffice.org、Apache 以及一些数不清的小项目的开发。gcc 无疑处在开源软件的核心地位。
作为自由软件的旗舰项目,Richard Stallman 在十多年前刚开始写作 gcc 的时候,还只是把它当作一个C程序语言的编译器;gcc 的意思也只是 GNU C Compiler 而已。经过这么多年的发展,gcc 已经不仅仅能支持C语言,它现在还支持 Ada、C++,Java、Objective-C、Pascal、COBOL 以及函数式编程和逻辑编程的 Mercury 语言等。因此,现在的 gcc 已经变成了 GNU Compiler Collection,也即是 GNU 编译器家族的意思了。这个名称同时也说明了 gcc 对于各种硬件平台无所不在的支持,甚至包括一些生僻的硬件平台。
gcc 不仅功能非常强大,结构也异常灵活。最值得称道的一点就是,它可以通过不同的前端模块来支持各种语言,如 Java、Fortran、Pascal、Modula-3 和 Ada 语言等。
实际上,无论是 GCC 还是 G++, 他们的定位都仅仅是 Driver,最终他们都是仅仅负责调用真正的编译器,来把源码编译到汇编代码;
比如 C 语言的编译器是 cc1,而 C++ 语言的编译器是 cc1plus,随后,Driver 再调用 as,把汇编代码变成二进制代码;
最后,调用 ld把二进制代码拼在一起;
小结
GUN 虽然没有开发出操作系统,但是却开发出了很多系统级的自由软件,GCC 就是其中之一。
Clang
大厂 Apple 背书,开源的编译器,最早是为了处理 Apple 自己那一套 (ios sdk,XCode,Objective-C,Swift);
说到 Clang,就不得不提另一个编译器 LLVM;
LLVM提供了一套适合编译器系统的中间语言(Intermediate Representation,IR),有大量变换和优化都围绕其实现;经过变换和优化后的中间语言,可以转换为目标平台相关的汇编语言代码;
简而言之,最开始的时候,各个编译器都是自己生成汇编代码,各个编译器有自己对代码优化的骚操作;
后来大家发现,其实可以把这些骚操作统一起来搞一个后端编译器,不论什么编程语言,你只要符合我 IR 中间代码的规范,我这个后端编译器都能给你编译成对应平台的、优化极好的汇编,而这个后端编译器就是 LLVM;
甚至 Clang 之前都只是 LLVM 的一个子项目:Clang
下面是一些 Clang 的优点(相比于GCC):
- 编译速度更快:在某些平台上,Clang的编译速度要明显快于 GCC;
- 占用内存更小:Clang生成的AST所占用的内存通常是GCC的五分之一左右;
- 模块化的设计:Clang采用基于库的模块化设计,更易于IDE的集成及其他用途的重用;
- 诊断信息可读性强:在编译过程中,Clang会创建并保留大量详细的元数据 (metadata),这将更有利于调试和错误报告(想一想GCC非人类的报错提示?);
- 设计更清晰简单,容易理解,易于扩展加强;
- 与代码基础较为古老的GCC相比,学习曲线会显得更为平缓;
- Clang 开源协议不是 GPLv3;
- 大部分命令都兼容G++
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;
除了Clang ,这里也有一个 Clang++;
这两者的区别和 GCC 和 G++ 的区别类似,一个使用的是C的库,另一个使用的是C++的库;
相关笔记
- 编译连接过程
- 编译&so库