GCC与编译过程
GCC(GNU Compiler Colletion),GUN编译器套装,是一套由GNU开发的编程语言编译器。Linux系统下的GCC编译器实际上是调用其他不同的工具来完成预处理、编译、汇编和链接工作。
一、编译过程
在计算机的眼里,只有1和0。不幸的是,我们用C语言写出来的代码,计算机无法直接看明白。所以一个程序如果需要被计算机执行,那么就必须翻译成能被计算机读懂并执行的1和0。实现这一结果的过程,我们称之为编译。
编译包括以下步骤:预处理、编译、汇编和链接。具体过程如下:
1.预处理:
hello.c文件中,预处理指令(入#include,#define,#ifdef,#endif等)经过预处理器解释,将预处理指令展开或者覆盖、将注释删除、添加必要的调试信息之后生成hello.i文件。
对应的命令为:gcc -E hello.c hello.i,表示我们只对其进行预处理阶段。
2.编译
经过预处理器处理之后生成的.i文件仍然是文本文件,计算机无法直接执行。在编译的阶段,编译器需要做词法分析、语法分析,然后根据硬件平台生成对应的汇编文件。不同的硬件平台有不同的编译器。例如x86平台的编译器与ARM交叉编译器生成的汇编文件就大不相同,这也正是C语言实现跨平台最关键的一个步骤:根据硬件平台来编译C代码。
对应的命令:gcc -S hello.i hello.s
3.汇编
编译过后的.s文件,需要继续加工生成.o文件。gcc调用汇编器as将汇编源程序翻译为可重定位文件。可重定位文件指的是文件虽然是一个ELF的可执行指令流,但全局符号还没有定位。由于全局符号可以出现在不同的文件中,因此在编译的过程中需要确定其入口地址,因此,需要进行最后一个步骤,链接。
对应的命令:gcc -c hello.s hello.o
4.链接
经过汇编之后的文件,不能够直接运行,需要通过链接来将全局符号重定位以及合并相同的段。通常情况下,我们需要用它其他库中的函数,链接器就负责扎到我们需要的函数并将其链接进来。一个ELF文件中,会包含需要段,如.text,.data等以及一些自定义的段,链接器会根据链接脚本(如果有的话)将对应的段放在一起。经过以上四个步骤,一个程序就可以被运行了。
对应的命令:gcc -L