C-C++编译器-clang
2012-05-19 11:33:29 阿炯

Clang 是一个 C++ 编写、基于 LLVM、发布于类BSD许可证下的 C/C++/Objective C/Objective C++ 编译器,其目标(之一)就是超越 GCC。Clang项目包括Clang前端和Clang静态分析器等。

The goal of the Clang project is to create a new C, C++, Objective C and Objective C++ front-end for the LLVM compiler. You can get and build the source today.

Clang 开发事出有因,Wiki 介绍如下:
Apple 使用 LLVM 在不支持全部 OpenGL 特性的 GPU (Intel 低端显卡) 上生成代码 (JIT),令程序仍然能够正常运行。之后 LLVM 与 GCC 的集成过程引发了一些不快,GCC 系统庞大而笨重,而 Apple 大量使用的 Objective-C 在 GCC 中优先级很低。此外 GCC 作为一个纯粹的编译系统,与 IDE 配合很差。加之许可证方面的要求,Apple 无法使用修改版的 GCC 而闭源。于是从2005年前后 Apple 决定从零开始写 C family 的前端,也就是基于 LLVM 的 Clang 了。目的是输出代码对应的抽象语法树(Abstract Syntax Tree, AST),并将代码编译成LLVM Bitcode。接着在后端(back-end)使用LLVM编译成平台相关的机器语言。


在Clang语言中,使用Stmt来代表statement。Clang代码的单元(unit)皆为语句(statement),语法树的节点(node)类型就是Stmt。另外Clang的表达式(Expression)也是语句的一种,Clang使用Expr来代表Expression,Expr本身继承自Stmt。节点之下有子节点列表(sub-node-list)。

Clang本身性能优异,其生成的AST所耗用掉的内存仅仅是GCC的20%左右。FreeBSD操作系统自2014年1月发行的10.0版本开始将Clang/LLVM作为默认编译器。测试证明Clang编译Objective-C代码时速度为GCC的3倍,还能针对用户发生的编译错误准确地给出建议。


特性
1、快:通过编译 OS X 上几乎包含了所有 C 头文件的 carbon.h 的测试,包括预处理 (Preprocess),语法 (lex),解析 (parse),语义分析 (Semantic Analysis),抽象语法树生成 (Abstract Syntax Tree) 的时间,Clang 是 Apple GCC 4.0 的 2.5x 快(2007年7月下旬数据)。

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

3、诊断信息可读性强:我不会排版,推荐去网站观看。其中错误的语法不但有源码提示,还会在错误的调用和相关上下文的下方有~~~~~和^的提示,相比之下 GCC 的提示较晦涩。

4、设计清晰简单,容易理解,易于扩展增强。与代码基础古老的 GCC 相比,学习曲线平缓。Clang 采用的是 BSD 协议的许可证,而 GCC 采用的是 GPL 协议,显然前者更为宽松;Clang 是一个高度模块化开发的轻量级编译器,编译速度快、占用内存小、有着友好的出错提示。

5、基于库的模块化设计,易于 IDE 集成及其他用途的重用。由于历史原因,GCC 是一个单一的可执行程序编译器,其内部完成了从预处理到最后代码生成的全部过程,中间诸多信息都无法被其他程序重用。Clang 将编译过程分成彼此分离的几个阶段,AST 信息可序列化。通过库的支持,程序能够获取到 AST 级别的信息,将大大增强对于代码的操控能力。对于 IDE 而言,代码补全、重构是重要的功能,然而如果没有底层的支持,只使用 tags 分析或是正则表达式匹配是很难达成的。


Clang是一个编译器,目前用来编译C、C++、Objective-C语言。它是一个编译器前端,其将上述的C类语言编译成一种“汇编语言(中间语言)”。接着通过LLVM(Low Level Virtual Machine)作为后端,将这种“汇编语言”编译成针对不同机器的二进制机器语言。它在类BSD许可证下发布,所以不必担心像GPL下发布的GCC那样,不能在商业软件中使用。

Clang/LLVM的特性

真正的自由:Clang是在类BSD许可证下发布,所以不必担心像GPL下发布的GCC那样,不能在商业软件中使用。而GPL的“自由”,以人人观点就是象牙塔里的“自由”。而真正推动社会进步的力量,其中很重要的一步是经济力量。虽然GPL没有禁止软件的商业用途,但是其强制开放源码的策略,让许多试图在部分闭源的软件中使用开源软件公司望而却步。当然这仅仅从商业上的软件重用的角度来看待问题的。在刺激和保障开源软件的连续性上,GPL的用途是不可磨灭的。

方面的学习:GCC的参与者众多,代码参差不齐,开发年限很长,因而庞大而臃肿,对于试图初学编译器相关知识的朋友来说,阅读GCC的源码会让人有点不知所措。而Clang却轻盈许多,代码简单易懂,占用内存小。根据Apostolou Dimitrios于2011年7月5日在GCC开发邮件列表中GSOC-Student Roundup的邮件中所说的一段话:“对我来说,阅读GCC代码库已变得非常困难。事实上这是我唯一所知道的随着时间的流逝而变得越来越复杂的项目”(译自维基百科);如果想学习编译器的相关知识,不妨尝试阅读Clang/LLVM的代码。

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

当前 Clang 还处在不断完善过程中,相比于 GCC,其在以下方面还需要加强:
支持更多语言: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。

另外,FreeBSD 10及其之后发行版本以Clang来代替GCC

Clang使用

写好一个C语言的Hello World之后(文件名为test.c)。
#include <stdio.h>

int main(int argc, char **argv){
printf("Hello FreeOA!\n");
return 0;
}

在对应的文件夹下(假设已经安装好Clang),输入:
clang test.c

就可以编译出常见的a.out了,这时输入a.out就可以在终端显示出结果了。

撇开编译器上的常见用途。Clang的优势有:拥有清晰的错误提示;模块化设计,方便二次开发(非常重要);可与IDE完美结合!



最新版本:13.0


项目主页:http://clang.llvm.org/