一、简介
GCC(GNU Compiler Collection,即GNU编译器套件)是由GNU开发的编程语言译器。GNU编译器套件包括C、C++、 Objective-C、 Fortran、Java、Ada和Go语言前端,也包括了这些语言的库(如libstdc++,libgcj等。) GCC(特别是其中的C语言编译器)也常被认为是跨平台编译的事实标准。
Linux系统下的GCC编译器实际上是GNU编译工具链其中的一款软件,GCC不仅功能强大、性能优越,其执行效率比一般编译器高20%~30%,并且是开源免费的。
二、编译过程
计算机或者CPU只能“读懂”二进制文件,读不懂文本文件中的源代码,因此需要进行一个编译过程将一个源代码的文本文件转化为机器能识别的二进制指令文件,那么GCC就可以帮我们达到这个目的。
比如我们常用的编译命令:
gcc hello.c -o hello
上述命令意思是:使用gcc编译工具将当前目录下的hello.c转化为二进制文件hello;其中-o的意思是output,指明生成的二进制文件名,若不写-o hello,则默认生成一个a.out文件。
而实际上,由.c文件转化成二进制文件,要经历四个步骤,如图:
1.预处理
调用预处理器cpp,执行文件包含、宏定义、条件编译 等工作。另外注释删除、添加必要的调试信息也在该阶段。
如果想获得C源程序经过预处理之后的文件,方法如下:
gcc hello.c -o hello.i -E
得到一个.i的文本文件,这样我们就可以查看源程序宏展开的样子。
2.编译
四个步骤中最复杂的阶段,包括词法和语法的分析,使用ccl,最终生成对应硬件平台的汇编语言(如果是GCC则生成x86格式的汇编文件,如果是ARM平台的交叉编译,则生成ARM格式的汇编文件)。
如果想获得C源程序经过预处理和编译之后的文件,方法如下:
1)由.c文件生成:gcc hello.c -o hello.s -S
2)由.i文件生成:gcc hello.i -o hello.s -S
得到一个.s文件,这是一个x86格式的汇编程序文件。
3.汇编
调用汇编器as将汇编源程序翻译成为ELF格式的可重定位文件,但是程序程序中的全局符号尚未定位,所以还不能直接运行。
如果想得到这样的文件,方法如下:
1)由.c文件生成:gcc hello.c -o hello.o -c
2)由.i文件生成:gcc hello.s -o hello.o -c
4.链接
经过以上三个步骤得到的二进制文件还需要经过重定位和合并相同权限的段。一般情况下,我们编译一个程序通常都需要链接系统的标准C库、gcc内置库等基本库文件。
gcc hello.o -o hello -lc - lgcc
-lc和-lgcc可省略
三、编译选项
选项 | 作用 | 示例 |
---|---|---|
-o | 指定输出文件名 | gcc a.c-oa |
-E | 输出预处理后的代码文件 | gcc a.c-oa.i-E |
-S | 输出编译后的汇编代码文件 | gcc a.c-oa.s-S |
-C | 输出链接后的可重定位文件 | gcc a.c-oa.o-c |
-g | 在编译结果中加入调试信息 | gcc a.c-oa-g |
-Ipath> | 指定头文件路径 | gec a.c-oa-L/include |
-L
| 指定库文件路径 | gec a.c-oa-L./lib |
-O | 指定优化等级 | gcc a.c-oa-O 2 |
-static | 使用静态链接 | gcc a.c-oa-lxxx-static |
-Wall | 打开所有的警告 | gec a.c-oa-Wall |