GCC源代码阅读

获取GCC源代码

阅读源代码的第一步是获取源代码,巧妇难为无米之炊嘛!

使用以下任意方法均可获得gcc源代码:

  1. svn checkout svn://gcc.gnu.org/svn/gcc/trunk SomeLocalDir (摘自http://gcc.gnu.org/svn.html)
  2. git clone git://gcc.gnu.org/git/gcc.git(摘自http://gcc.gnu.org/git/?p=gcc.git;a=summary)

需要注意的是,第二种方法得到的代码并非是svn的所有历史镜像。因为gcc的svn分支不是全部位于svn://gcc.gnu.org/svn/gcc/branches/这一层,其中如redhat或者google等实际起到名字空间的作用,再下一层才是真正的分支内容,然而svn到git转换的脚本不能识别这种情况,因此所有这类位于第二层的分支都不存在于git镜像中。

当然对于初学者来说并不重要,我们只要盯住一个版本看就好了,比如4.5.2或者4.4.5(原本想等4.6发布之后再开始这个学习系列,目前看来一半时是等不到了)。由于我之前在4.4.5上有一点积累,因此如没有特别说明,这一系列的心得都是通过阅读4.4.5的代码而来。

使用源代码交叉索引工具

拿到源代码之后,建议使用代码交叉索引工具生成索引,方便阅读。常用的有etags(或者ctags)和cscope。

etags

gcc的Makefile里有生成TAGS文件的target,可以直接在编译目录下生成,如

$ mkdir build
$ cd build
$ ../gcc/configure --enable-languages=c,c++,lto
$ make
$ make -k etags # OR `make -k tags'

在Emacs里加载TAGS文件的方法是:M-x visit-tags-table

cscope

cscope的配置也不复杂,以下是在Ubuntu 10.10下安装配置步骤

$ sudo apt-get install cscope cscope-el
$ cd gcc
$ gcc-cscope.sh

gcc-cscope.sh脚本内容如下

#!/bin/bashBUILD_DIR=${1:-../build/gcc}
cscope-files.sh libiberty gcc include gcc/config/arm $BUILD_DIR >cscope.files
if [ -f cscope.files ]
thencscope -b -q -k
elseecho "cscope.files not found at $PWD."exit 1
fi

由于gcc的部分代码是在编译期生成的,所以除了索引源代码目录下的文件,还要索引编译目录下的文件(对应于BUILD_DIR这个变量所制订的目录,缺省为build/gcc,也可以通过参数使用其它目录)。

由于gcc支持多种硬件平台,为避免混淆,我只选择了自己关心的ARM部分代码,其它后端代码忽略。

cscope-files.sh脚本内容如下:

#!/bin/bashfor dir in "$@"
dofind "$dir" -maxdepth 1 -iname "*.[hc]" -type f
done

要想在Emacs里面使用cscope索引结果,需要安装cscope-el软件包,并把下面一行代码加入Emacs配置文件

(require 'xcscope)

具体使用方法可以参见/usr/share/emacs/site-lisp/xcscope.el文件内的注释。

下载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源代码,离不开各种参考资料,如论文、wiki、手册和散落在邮件列表里面的讨论。

如果没有理论背景知识,想从GCC源代码里看出它想要做什么,以及在做什么,是很困难的。因此,学习GCC实现的过程,必然伴随着不断地阅读论文。如果注释里面提到了参考论文(或书籍)的名字,不妨直接找来看看。另外一个非常重要的内容就是gcc summit,论文下载地址为http://gcc.gnu.org/wiki#GCC_Summit_Proceedings,包括从2003年至今的所有论文。

gcc summit的论文不涉及太多的细节,所以看起来不像其它论文那么头疼,但是要学习具体的算法和实现,还是要找来相应的论文,啃硬骨头。论文看多了,如何管理也是个问题,不然看了等于白看,一会儿就还给作者了。尝试了两个网站CiteULike和Connotea,都不理想,似乎更像是社会化书签服务,对于我一地的PDF毫无帮助。最后还是用orgmode记录,以后再把RefTex集成进来。

要了解GCC的实现细节,还要看手册,Ubuntu下的安装方式如下:

sudo apt-get install gcc-doc

其中包括两个手册——使用手册和内部实现手册,查看方式分别为:

info gcc
info gccint

手册不适合从头到尾看下来,需要的时候查找相应内容学习就可以了,最多粗读一遍获得大概的印象,依我的经验,基本就是看了后面忘了前面,反而是遇到问题再来查找更有针对性、更容易理解。由于gccint始终处于不完整状态,所以也不要期望太多,看代码是必不可少了。

手册的在线地址为http://gcc.gnu.org/onlinedocs/。

最后的信息源就是gcc wiki和邮件列表了,由于时效性的问题,上面的内容是否还适用,需要个人自行判断。邮件列表有多个,我个人关注的是gcc和gcc-patches,


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/454069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx 动静分离

页面动静分离 后端 调用tomcat 集群 示例: server { listen 80; server_name www.www2.com ; root /web/www2/htmlloation /img/ {alias /web/www2/html/img/;}location ~ (\.jsp)|(\.do)$ {proxy_pass http:## //serverip:port;proxy_redirect off;// 重定向 指…

Linux 状态命令之内存状态 vmstat

语法 vmstat 常见命令格式如下: vmstat [-a] [-n] [-S unit] [delay [ count]] vmstat [-s] [-n] [-S unit] vmstat [-m] [-n] [delay [ count]] vmstat [-d] [-n] [delay [ count]] vmstat [-p disk partition] [-n] [delay [ count]] vmstat [-f] vmstat [-V]命…

使用OpenSSL实现CA证书的搭建过程

个人博客地址:http://www.pojun.tech/ 欢迎访问 什么是CA CA,Catificate Authority,通俗的理解就是一种认证机制。它的作用就是提供证书(也就是服务端证书,由域名,公司信息,序列号,签名信息等等组成&#…

最近公共祖先 python_求二叉搜索树的最近公共祖先

给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。百度百科中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”…

gdb使用实例

第一篇 概论我们将学习使用gdb来调试通过一个通过串行线同PC相连的嵌入式系统。Gdb可以调试各种程序,包括C、C、JAVA、PASCAL、FORAN和一些其它的语言。包括GNU所支持的所有微处理器的汇编语言。在gdb的所有可圈可点的特性中,有一点值得注意,…

Linux 监控命令之 netstat

netstat命令用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。netstat是在内核中访问网络及相关信息的程序,它能提供TCP连接,TCP和UDP监听,进程内存管理的相关报告。 语法 netstat [-acC…

C#递归搜索指定目录下的文件或目录

来源:https://www.cnblogs.com/huhangfei/p/5012978.html诚然可以使用现成的Directory类下的GetFiles、GetDirectories、GetFileSystemEntries这几个方法实现同样的功能,但请相信我不是蛋疼,原因是这几个方法在遇上【System Volume Informati…

solr 配置

创建 SolrHome(solrCore) 1.解压 solr-4.10.4.tgz 到 /usr/local/solr 2.将 solr-4.10.4/example/solr 下所有文件拷贝到 /usr/local/solrhome (此 solrhome 为自己创建的) solrhome 是 solr 运行主目录,可包含多个 SolrCore 目录SolrCore 目录中包含运行 Solr 实例…

mfc程序转化为qt_10年程序员:我都学过这些语言,2019年开始我再也不是程序员......

为什么学编程2008年,高中毕业的我问一个已经工作两年的亲戚:什么专业工资高?他告诉我:程序员。2008年成都最低工资好像是800元,我的生活费也是800元,据他所说程序员出来的工资是2000,于是开始了…

day 7 引用

1.ba在c语言和python中的区别 c语言:a100 a变量里面放的100 b a b变量里面也放的100 python : a100 内存中有个100 a放的100的内存地址 b a b也放的100的内存地址 相当于给100那一块内存,贴个便利签 2.type查看数据类型&…

Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示...

Dapper的牛逼就不扯蛋了,答应群友做个入门Demo的,现有园友需要,那么公开分享一下: 完整Demo:http://pan.baidu.com/s/1i3TcEzj 注 意 事 项:http://www.cnblogs.com/dunitian/p/5221058.html 平台之大势何人…

Linux 状态命令之磁盘状态 iostat

Linux系统中的iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。同vmstat一样,iostat也有一个弱点,就…

GDB十分钟教程

GDB十分钟教程 作者: liigo 原文链接: http://blog.csdn.net/liigo/archive/2006/01/17/582231.aspx 日期: 2006年1月16日 本文写给主要工作在Windows操作系统下而又需要开发一些跨平台软件的程序员朋友,以及程序爱好者。 GDB是一个由GNU开源组织发布的、UNIX/LI…

课后作业-阅读任务-阅读提问-3

1.如果两个人合作的始终达不到规范阶段该怎如何处理? 2. 逻辑和界面设计要注意哪些因素?转载于:https://www.cnblogs.com/fhycm/p/7866548.html

ride上点击用例不能显示edit信息_接口测试平台代码实现61: 多接口用例1

终于又序更上了,原谅最近作者几天事情不断。按照我们之前的计划,需要迅速开启很重要的核心多用例接口。首先,我们要确定,这个功能的大体设计。就放在在我们的页面 用例库 中:所以也就是我们很久之前就创建好的P_cases.…

黑客攻防专题八:21种RING的提权方法

好多都没有成功,还是发来看看,看看思路,呵呵 以下全部是本人提权时候的总结 很多方法至今没有机会试验也没有成功,但是我是的确看见别人成功过的。本人不才,除了第一种方法自己研究的,其他的都是别人的经验…

Linux 状态命令之内存状态 free

简介 free指令会显示内存的使用情况&#xff0c;包括实体内存&#xff0c;虚拟的交换文件内存&#xff0c;共享内存区段&#xff0c;以及系统核心使用的缓冲区等。 语法 free [-bkmotV][-s <间隔秒数>]参数说明&#xff1a;-b  以Byte为单位显示内存使用情况。-k  以…

SpringMVC在使用Jackson2时关于日期类型格式化的问题

*本例程序使用Jackson2.9.0&#xff0c;jackson1.x的处理方式稍稍有些不同。 在基于Spring&SpringMVC的Web项目中&#xff0c;我们常使用Jackson(1.x/2.x)来增加程序对Json格式的数据的支持。 因此&#xff0c;在实际应用中有个常见的需求&#xff1a;日期的格式化。 假设&…

GDB 使用——Linux C编程

简述 一 列文件清单 二&#xff1a;执行程序 三&#xff1a;显示数据 四&#xff1a;断点(breakpoint) 五&#xff0e;断点的管理 六&#xff0e;变量的检查和赋值 七. 单步执行 八&#xff0e;函数的调用 九&#xff0e;机器语言工具 …

python拨号_python 拨号代码(win10 系统亲测有效)

# -*- coding: utf-8 -*-import win32rasimport time,osdef Connect(dialname, account, passwd):dial_params (dialname, , , account, passwd, )return win32ras.Dial(None, None, dial_params, None)def DialBroadband():dialname u宽带连接 #just a nameaccount u059291…