GCC的编译过程
一、预处理:
对源程序中的伪指令(即以#开头的指令)和特殊符号进行处理的过程,即进行头文件的展开,宏替换,条件编译
如以下的一段简单程序:#include<stdio.h>
int main(){int a;int b;int sum;sum = a + b ;printf("add = %d\n",sum);return 0;}
在Gcc中输入“gcc -E main.c -o main.i”可使程序暂停在预处理阶段,但注意的是在预处理阶段,gcc不做语法的检查,只是把.c的后缀名变成.i的
二、编译阶段
编译就是将源程序转换为计算机可以执行的二进制代码。在这个阶段可以对语法进行检查,对词法进行分析。此时文件的后缀名变为.o
再GCC中输入"gcc -S main.c -o test.s"可使程序暂停在编译阶段。
三、汇编阶段
汇编的过程实际上是将汇编语言代码翻译成机器语言的过程。
产生一个扩展名为.s的目标文件。通过在GCC中输入"gcc -c main.c -o main.o"可使程序暂停在汇编阶段。
四、链接阶段
目标代码不能直接执行,要想将目标代码变成可执行程序,还需要进行链接操作。才会生成真正可以执行的可执行程序。
链接操作最重要的步骤就是将函数库中相应的代码组合到目标文件中。
进入了这个阶段之后,就牵涉到一个重要的概念——函数库,一般分为静库态和动态库两种。
静态库:以".a"为后缀名,在编译时将库文件里的代码搬运到可执行文件中。
动态库:以".so"为后缀名,在执行时将库文件里的代码搬运到可执行文件中。
静态库优缺点是:可执行文件体积大,编译效率低,执行效率高,不易于升级,代码布局更好。
动态库优缺点是:可执行文件体积小,编译效率高,执行效率低,易于升级,代码布局混乱。
存放位置:系统的库文件存放于根目录下的lib文件中,软件中的库文件存放在根目录下的/usr/lib中。
printf、scanf、strcpy等函数存放在libc.a或者libc.so中
数学函数放在libm.a或者libc.so中。