GCC vs Clang:两大编译器巨头的龙争虎斗
GCC vs Clang:两大编译器巨头的龙争虎斗
GCC(GNU Compiler Collection)和Clang/LLVM是两大主流编译器,它们在编译器领域都有着举足轻重的地位。GCC最早可以追溯到2000年,而Clang/LLVM大约是2010年。要对比两个软件的性能并不容易,但我会尽量保证公平、全面。
GCC:不只是编译器,更是编译器套件
先来说说GCC。1984年,当Richard Stallman创立GNU项目时,其目标是创建一个完善的类似Unix操作系统的自由软件。提醒大家,当时Linux还没出现,Linux是后来替代Unix的操作系统,所以自由软件的概念在当时的确是一个伟大的目标。那时候,C语言是系统软件开发的主导语言,Richard开始为C语言开发编译器,并将其命名为GNU C(GCC)。转眼,今年4月,GCC的版本已经发展到了10.3,从C语言编译器发展成为跨平台编译器,支持以下多种语言:
- C
- C++
- Objective-C
- Fortran
- Ada
- Go
- D
GCC几乎可以适用于所有类似Unix的系统,也可以借助MinGW在Windows系统中使用。GCC本身是用C语言编写的,使用工具Autotools、Bison和Make进行构建。GCC维护简单,任务和视图清晰明了,具体可点击链接了解。为了确保GCC能继续自由软件的精神,其主要产品的发布由一个专门的委员会监督,这个委员会由来自不同组织的权威人士组成。
Clang/LLVM:编译器的“龙头”
CLAN/LLVM是一个支持C、C++、Objto-C等多种语言的编译器工具链。这句话并不能证明Clang/LLVM力量的强大。为了解释为什么我对这个编译工具情有独钟,我需要更详细地描述一下现代编译器的架构:
Clang/LLVM就是这种架构的典型例子。LLVM最初是美国伊利诺伊大学的一个研究项目。Clang是前端,LLVM是后端。LLVM定义了一个基于单一静态赋值(SSA)形式的中间表示(IR)。许多编译优化因此更容易在IR上执行。还可以添加LLVM IR pass来添加自定义优化步骤。总而言之,这些工具推动着Clang/LLVM成为顶尖的编译器工具链。
GCC Vs Clang
现在让我们来比较一下两大编译器巨头:GCC和Clang。
- 开源软件 ——众所周知,GCC和Clang都是免费的开源软件。但是他们的许可授权很不一样。GCC是参照GPL(GNU公共许可证)授权的,而Clang/LLVM是Apache许可授权的。比较GCC和Clang的许可授权,最专业的是律师。
- 支持平台 ——GCC和Clang都支持几乎所有的平台。Clang/LLVM可在Windows本机上进行编译,而GCC则需要MinGW这样的子系统,才能与Windows兼容。这样比较Clang和GCC是不公平的,因为GCC没有在本地支持Windows的计划。
- 代码复杂度 ——GCC是一个非常复杂的软件,有超过1500万行代码。尽管其前/后端定义清晰明了,但软件在本质上更为单一。对比GCC,Clang更多的是模块化架构,具有定义良好的扩展点。
- 标准支持 ——对C++20,即最新推出的C++版本,GCC已通过测试。另外,它也完全符合C++17以及最新的C语言标准,C17。Clang完全符合C++17标准,也将很快跟进C++20标准。
- 高效代码生成——Clang和GCC的代码生成,在空间和时间的复杂度旗鼓相当。因此这种比较毫无意义,因为这两个编译优化工具都基于一种严密的静态分配形式。
- 语言独立的类型系统 ——在这个标题下对比Clang与GCC很有意义。由于Clang/LLVM对所有兼容语言都使用语言独立的类型系统,因此可以确定指令的确切语义。GCC则没有语言独立类型系统的设计目标。
- 前端解析器——GCC以前有基于Bison的LR解析器,后来转向了手写递归下降解析器。Clang一直使用手写的确定性递归下降解析器,且可回溯。
- 后端链接器 ——GCC与Clang的差异在这个层面最为明显。GCC使用ld作为链接器,支持ld-gold。Clang使用lld作为链接器。通过一些基准测试,可以看出lld比ld甚至最新的ld-gold都快。
- 构建工具——Clang与GCC的另一个大的区别。GCC使用Autotools和Make作为构建工具,而Clang/LLVM使用CMake。
- 调试支持 ——GCC有一个优秀的GDB调试器。GDB历经时间考验,性能优异。Clang则将LLDB调试器构建为LLVM上的一组可重用组件。
以下的表格简单梳理了两个工具的差异:
类别 | GCC | Clang/LLVM |
---|---|---|
许可证 | GNU GPL | Apache 2.0 |
代码模块化 | 一体化架构 | 模块化 |
支持平台 | *inx, Windows (MinGW) | *inx, Natively in Windows |
符合的语言标准 | C++20已通过验证, 符合C++17 | 符合C++17,正在申请C++20标准 |
代码生成 | 高效,有很多编译器选项可以使用 | 高效,LLVM后端使用了SSA表单 |
语言独立类型系统 | 没有 | 有(LLVM的设计初衷) |
构建工具 | 基于Make | CMake |
解析器 | 最早采用Bison LR,现在改为递归下解析器 | 手写的递归下降解析器 |
链接器 | LD | lld |
调试器 | GDB | LLDB |
总结
这篇博文可以帮助你理解GCC和Clang的主要区别。GCC是一个成熟的编译器,支持多种语言。Clang主要支持C语言、C++和Objtovi-C。但是Clang的底层框架LLVM具有足够的可扩展性,可以支持Julia和Swift等较新的语言。从C++的角度来看,这两种都是符合C++17标准的优秀编译器。
从Incredibuild角度来看,两者都是很好的工具。这就是为什么我们也与Clang和GCC都兼容。借助Incredibuild的创新技术,Clang和GCC编译进程可以无缝地分布在网络中的数百个远程内核上,大大减少了Clang和GCC的编译时间。