GCC详解


GCC编译过程

GCC是Linux上功能最强大的C语言编译器,在使用GCC编译程序的时候,编译过程分为4个阶段:

预处理(Pre-Processing)

这一步,GCC调用预处理程序cpp,将源文件中定义的宏展开,并将#include头文件的内容插入源文件,生成一个以.i为后缀的新文件。

GCC -E 源码文件 -o 预处理生成文件

编译(Compiling)

这一步,GCC调用ccl程序将预处理生成的.i文件编译成以.s为后缀的汇编文件。

GCC -S 预处理后的文件/源文件 -o 汇编文件

汇编(Assembling)

这一步,GCC调用as程序将.s文件汇编成机器代码.o的目标文件。

GCC -c 预处理后的文件/汇编文件/源文件 (-o 目标文件)

链接(Linking)

这一步,GCC将调用ld程序将所有的目标文件链接成一个可执行程序。

GCC 所有目标文件 -o 可执行程序名称

以上是GCC编译一个源文件的四个步骤,但现实的项目中往往会有很多的源码文件,如果使用命令行方式一个一个编译,不仅费时费力,还很容易出问题,这时候就需要使用到make这个工具,在本文中暂不讨论make这个工具。

GCC警告信息

GCC提供了警告功能,包含完整的错误检查,可以帮助我们检查出一些潜在的错误,从而帮助我们写出更加专业和优美的代码。

GCC能够提供很多种警告信息,其中最有用的当属-Wall了,使用这个选项可以使GCC产生尽可能多的警告信息。这些警告从严格意义上说算不上是错误,但可能会是潜在的错误,这里就引出另外比较有用的选项-Werror,带上这个选项,GCC会在出现警告的地方停止编译。

库依赖

在程序开发中经常会使用到一些第三方库,特别在开放的Linux平台上更甚。从程序上来看,第三方库其实就是一些头文件和一些库文件的集合,在程序中include头文件,编译的时候链接库文件。在Linux下大多数函数都默认将头文件放在/usr/include/目录下,将库文件放在/usr/lib/下,但这并不能代表所有的情况,所以GCC在编译时需要有其他的方法來查找需要的头文件与库文件。

GCC是采用的搜索目录的方式來查找所需文件,-l可以向GCC头文件搜索路径添加目录,-L添加库文件目录,格式如下例:

GCC -c main.c -l /home/include/

GCC -c main.c -L /home/lib/ -l**, -l**是一个约定俗成的用法,Linux下面所有的库应该以lib开头,比如libtest.so或者libtest.a,那么链接的时候就使用 -ltest 即可,GCC会自动找到libtest.so或者libtest.a,GCC会默认使用动态链接,只有指定 -static 选项时,才会强制使用静态链接库。

GCC代码优化

GCC可以通过设置-On选项对源码进行优化,不同的n值代表不同的优化级别

编译时使用 -O 等价与 -O1 的效果,告诉GCC减小代码长度和执行时间。

使用-O2,除了O1的效果外,还要做一些额外的优化,比如调整处理器指令调度等。

-O3在O2基础上,会做一些循环展开和与处理器特性相关的优化工作。

n值越高,优化会做得愈彻底,这也意味着原有的代码结构可能会被改变,所以优化将会给程序的调试和跟踪带来困难。

调试

利用GCC的 -g 选项可以生成调试信息便于使用GDB调试程序。

相关内容