透过源码领悟GCC到底在干些什么 GCC源码分析

如题所述

 上半年一直在做有关GCC和LD的项目,到现在还没做完。最近几天编程的那台电脑坏了,所以趁此间隙写一点相关的分析和经验之类的跟大家共享。
  一、GCC的作用和运行机制
  GCC是Linux下重要的编译工具,用法这里就不说了,满大街都找得到。这里我重点介绍GCC的运作机制,作为代码分析的铺垫。全篇使用C语言子部件来作分析,因为我对其他语言的编译没有研究。
  根据编译原理,语言的编译分为这么几个步骤:词法分析、语法分析、语义分析、中间语言生成、优化、目标代码生成等。然而从编译器使用的角度来看,要把源代码翻译为可执行文件要经过编译和连接两步,与此对应,一个完整的编译系统一定包含编译器和连接器两大功能部件。编译器要完成编译原理中提到的那些任务;连接器要把编译器生成的代码片段拼接成一个完整的可执行程序。之所以需要连接器,是因为一般的程序都是多源文件的,而编译器一次只编译一个源文件(称之为翻译单元translation unit),因此需要连接器把所有翻译单元对应的输出合并成一个可执行文件。
  如果一切顺利,可执行程序就可以正确的生成出来。但是一旦源代码存在某些问题,错误就会被报告出来。编译器报告的错误一般都是局部错误,它会指明错误在哪个文件第几行;连接器报告的错误一般都是全局错误,而且绝大多数都是多胳膊少腿的问题,比如函数重定义,无法解决的外部符号等,这些错误无法定位到某一行。
  GCC就是这里的编译器。准确来说,GCC是一个编译驱动器,驱动cc1、as和ld三个部件完成编译、汇编和连接的工作。cc1将C语言源文件编译为汇编文件(.s)。而将汇编代码转换为二进制指令的工作由AS完成,生成大家都很熟悉的对象文件(.o);生成的这些对象文件再由AR程序打包成静态库(.a),或者由LD程序连接成可执行程序(elf、.so或其他格式)。而LD就是所谓的连接器。AS、AR、LD是属于另外一个叫做binutils的软件包的程序,所以要让GCC能够有效运作起来,除了在系统中安装GCC外,还要安装binutils才行。
  以下是cc1、as、ld各司其责的配合完成一个编译过程。

  [plain] view plaincopy
  gcc test.c -S -o test.S
  as test.S -o test.o
  ld test.o -o test
  通常所用的“gcc -c”就相当于“gcc -S” + as,而对于编译单个源文件一步到位生成可执行“gcc test.c -o test”相当于上面三个步骤的组合,中间文件被放置在临时目录下。从这一点看来,GCC除去编译的功能外,更像是个driver,它可以驱动as和ld完成整个的编译,特别是gcc也接受对象文件(.o)和静态库(.a)作为参数用于生成可执行程序,其实背后就是调用的LD,还可以用“-Wl,”选项给LD传递自定义参数。所以在大多数软件的Makefile里,你很难找到AS和LD的字眼,gcc已经给你包办了。
  GCC源代码里包含的主要就是cc1这部分(还包括一些其他的辅助工具,比如collect2等)。

  二、GCC的安装
  要学习和修改GCC源码,首先第一步是在自己的机器上用GCC源代码编译出一个选定版本的GCC(这里以gcc-4.5.2.tar.bz2为例,源码可以从http://gcc.gnu.org去下载)。除此之外,GCC依赖于gmp、mpfr、mpc三个库,如果你机器上没有,或者版本太老以至于无法支持新的GCC,那么你还得去把这三个库下载下来。
  一般来说,下载GCC是从GNU的FTP镜像网站去下载,gcc的代码包一般放置在/release/gcc-x.y目录下,而那三个依赖库一般放置在/infrastructure/目录下。
  1、把依赖库和GCC解包

  [plain] view plaincopy
  tar -vjxf gmp-4.3.2.tar.bz2 -C /usr/src/
  tar -vjxf mpfr-2.4.2.tar.bz2 -C /usr/src/
  tar -vxf mpc-0.8.1.tar.gz -C /usr/src/
  tar -vjxf gcc-4.5.2.tar.bz2 -C /usr/src/

2、到自己的home目录下编译依赖库

  [plain] view plaincopy
  cd ~
  mkdir gmp-build
  cd gmp-build
  /usr/src/gmp-4.3.2/configure --prefix=/usr/local/gmp-4.3.2 #指定安装位置
  make
  make check
  make install
  
  cd ~
  mkdir mpfr-build
  cd mpfr-build
  /usr/src/mpfr-2.4.2/configure --prefix=/usr/local/mpfr-2.4.2 --with-gmp=/usr/local/gmp-4.3.2
  make
  make check
  make install
  
  
  cd ~
  mkdir mpc-build
  cd mpfr-build
  /usr/src/mpc-0.8.1/configure --prefix=/usr/local/mpc-0.8.1 --with-mpfr=/usr/local/mpfr-2.4.2 --with-gmp=/usr/local/gmp-4.3.2
  make
  make check
  make install

3、编译GCC

  [plain] view plaincopy
  cd ~
  mkdir gcc-build
  cd gcc-build
  /usr/src/gcc-4.5.2/configure --prefix=/usr/local/gcc-4.5.2 --with-mpc=/usr/local/mpc-0.8.1 --with-mpfr=/usr/local/mpfr-2.4.2 --with-gmp=/usr/local/gmp-4.3.2 --enable-languages=c,c++
  make
  make install
温馨提示:答案为网友推荐,仅供参考
相似回答