4.3.5 编译器gcc(1)
编译器的作用是将用高级语言或者汇编语言编写的源代码翻译成处理器上等效的一系列操作命令。对嵌入式系统来说,其编译器数不胜数,其中gcc是非常优秀的编译工具。
最初,gcc只是一个C语言编译器,是GNU C Compiler 的英文缩写。随着众多自由开发者的加入和gcc自身的发展,如今的gcc已经是一个包含众多语言的编译器了。其中包括 C、C++、Ada、Object C和Java等。如今的gcc具有了交叉编译器的功能。所谓交叉编译,即在一个平台下编译另一个平台的代码。
gcc编译器能将C、C++语言源程序、汇程式程序和目标程序编译、连接成可执行文件,如果没有给出可执行文件的名字,gcc将生成一个名为a.out的文件。在Linux系统中,可执行文件没有统一的后缀。gcc通过后缀来区别输入文件的类别,下面我们来介绍gcc所遵循的部分约定规则,如表4-2所示。
表4-2 gcc支持的后缀名解释
|
后 缀 名< xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /> |
含 义 |
|
.c为后缀的文件 |
C语言源代码文件 |
|
.a为后缀的文件 |
由目标文件构成的档案库文件 |
|
.C、.cc或.cxx
为后缀的文件 |
C++源代码文件 |
|
.h为后缀的文件 |
程序所包含的头文件 |
|
.i 为后缀的文件 |
已经预处理过的C源代码文件 |
|
.ii为后缀的文件 |
已经预处理过的C++源代码文件 |
|
.m为后缀的文件 |
Objective-C源代码文件 |
|
.o为后缀的文件 |
编译后的目标文件 |
|
.s为后缀的文件 |
汇编语言源代码文件 |
|
.S为后缀的文件 |
经过预编译的汇编语言源代码文件 |
1. 编译过程
虽然我们称gcc是C语言的编译器,但使用gcc由C语言源代码文件生成可执行文件的过程不仅仅是编译的过程,而是要经历四个相互关联的步骤:预处理(也称预编译,Preprocessing)、编译(Compilation)、汇编(Assembly)和连接(Linking)。
预处理(Preprocessing):命令gcc首先调用cpp进行预处理,在预处理过程中,对源代码文件中的文件包含(include)、预编译语句(如宏定义define等)进行分析。
编译(Compilation):接着调用cc进行编译,这个阶段根据输入文件生成以.o为后缀的目标文件。
汇编(Assembly):汇编过程是针对汇编语言的步骤,调用as进行工作,一般来讲,.s为后缀的汇编语言源代码文件和汇编.s为后缀的汇编语言文件经过预编译和汇编之后都生成以.o为后缀的目标文件。
连接(Linking):当所有的目标文件都生成之后,gcc就调用ld来完成最后的关键性工作,这个阶段就是连接。在连接阶段,所有的目标文件被安排在可执行程序中的恰当位置,同时,该程序所调用到的库函数也从各自所在的档案库中连到合适的地方。
2. 编译选项
gcc的使用语法如下。
gcc [ options ] filenames …
其中options就是编译器所需要的参数,必须以"-"开始,而filenames给出相关的文件名称。在使用gcc的时候,必须给出必要的选项和文件名。gcc编译器的调用参数很多,我们不可能也没有必要全部记住。这里只介绍其中最基本、最常用的参数,如表4-3所示。
表4-3 gcc总体选项表
|
选 项 |
对 应 语 言 |
|
-c |
只编译,不连接成为可执行文件,编译器只
是由输入的.c等源代码文件生成.o为后缀的
目标文件,通常用于编译不包含主程序的子
程序文件 |
|
-o file |
确定输出文件的名称为file,同时这个名称
不能和源文件同名。如果不给出这个选项,
gcc就给出预设的可执行文件a.out |
|
-g |
产生符号调试工具(GNU的gdb)所必要的符
号资讯,要想对源代码进行调试,我们就必
须加入这个选项 |
|
-O |
对程序进行优化编译、连接,采用这个选项,
整个源代码会在编译、连接过程中进行优化处
理,这样产生的可执行文件的执行效率可以提高,
但是,编译、连接的速度就相应地要慢一些 |
|
-O2 |
比-O更好的优化编译、连接,当然整个编
译、连接过程会更慢 |
|
-I dirname |
将dirname所指出的目录加入到程序头文件目
录列表中,是在预编译过程中使用的参数 |
|
-L dirname |
将dirname所指出的目录加入到程序库
文件目录列表中 |
|
-static |
链接静态库 |
|
-E |
只进行预编译,不做其他处理 |
|
- v |
打印编译器内部编译各个过程的命令
行信息和编译器版本 |
|
-S |
只编译不汇编,生成汇编代码 |
|
-library |
链接名为library的库文件 |
|
-Wall |
指定产生全部的警告信息 |
|
-pipe |
在编译过程的不同阶段间使用管道而非
临时文件进行通信 |