GCC源代码阅读(二)

下载gcc源代码,编译通过,测试hello world之后,就可以开始认真阅读它的实现了。

通常我们阅读的源代码,是开发过程中某一时刻的快照,在特定情况下,我们不仅需要理解它的当前实现方式,还要了解它的发展过程和原因。这时,我们可以借助版本管理工具、ChangeLog文件和邮件列表,来了解开发历史。

取决于获取源代码的方式,可以使用的版本管理工具有subversion和git,熟练使用命令行工具或者图形化客户端是必须的,如果能和开发环境无缝结合就更完美了。Emacs默认的VC软件包支持多种版本管理工具,包括subversion和git。VC的操作对象是文件,如果想要了解整个项目的情况,可以安装psvn和magit。

ChangeLog是个很有趣的东西,我一度对它的作用不太理解。有了版本控制工具,还要ChangeLog做啥?!而且ChangeLog的内容也很枯燥,它只记录了源代码的物理变化,比如增加了一个变量,并在哪个函数里使用;删除一个宏;或者改变函数调用关系等等。它并不记录做出这些改变的目的或原因。后来经jzhang918介绍,终于明白它对于版本管理工具的补充作用。通常,版本工具的操作对象是文件,因此,如果想知道某个函数(或者某个变量)发生了哪些变化,则相当棘手,ChangeLog的作用便在于此。

仅有历史版本和ChangeLog还是不够的,它们缺少了一项非常重要的信息——为什么要做这样的修改。一般来说,最好能在提交日志上说明,但很少有gcc的开发者这么做,所以,就要靠邮件列表来帮忙了。通常来讲,在提交修改之前,都需要把patch发到gcc开发者所用的邮件列表上,供maintainer检查,通过后才能提交。在邮件里,作者会讲一点来龙去脉,不然maintainer一头雾水,patch就无法通过了。

编译简介(五)

除了使用调试器查找程序缺陷之外,我们还可以检查编译过程中生成的文件。对于gcc来说,-c用于生成目标文件,-S生成汇编文件,而-E生成预处理文件。配合使用-save-temps,则可以生成多个文件,如

gcc -save-temps -c hello.c

生成并保留目标文件(hello.o)、汇编文件(hello.s)和预处理文件(hello.i

查看预处理文件最大的问题就是宏定义,因为宏都被预处理掉了,使用-E -dM选项,可以查看编译器到底定义了哪些宏。

gcc -E -dM hello.c