Linux下C语言程序的编译过程
使用gcc编译程序时,编译工程分为4个阶段:
(1)预处理:(Pre-Processing)
(2)编译:(Compiling)
(3)汇编:(Assembling)
(4)链接:(linking)
Linux程序员可以根据自己的需要让gcc在编译的任何阶段结束,以便检查或使用编译器在该阶段输出信息,或者对最后生成的二进制文件进行控制,以便加入不同数量和种类的调试代码来为今后的调试做好准备。和其他常用的编译器一样,gcc提供了灵活而强大的代码优化功能,利用它可以生成执行效率较高的代码。
在功能上,预处理、编译、汇编是3个不同的阶段,但gcc在实际操作时可以把3个步骤合并为一个步骤来执行。下面以一个实例介绍如何生成各个阶段的代码。
本小节的演示都针对文件 hello.c进行
1. /*
2. * hello.c
3. */
4.
5. #include <stdio.h>
6. int main()
7. {
8. printf(" Bettergoal, Better life! /n");
9. return 0;
10. }
第一阶段
在预处理阶段,输入的是C语言源文件,通常为*.c或者*.C,它们一般带有*h之类的头文件。这个阶段主要处理源文件中的#ifdef、#include和#define预处理命令。该阶段会生成一个中间文件*.i
1.生成预处理后的文件hello.i
$ gcc -E hello.c -o hello.i
它通过对源文件hello.c使用E选项来生成中间文件hello.i
第二阶段
在编译阶段,输入的是中间文件*.i,编译后生成汇编语言文件*.s。这个阶段对应的gcc命令如下所示:
2 .生成汇编语言文件hello.s
$ gcc-s hello.i -o hello.s
第三阶段
在汇编阶段,将输入的汇编文件*.s转换成二进制机器代码*.o,这个阶段对应的gcc命令如下所示:
$ gcc -c hello.s-o hello.o
第四阶段
在链接阶段,将输入的二进制机器代码文件*.o(与其他机器代码文件和库文件)汇集成一个可执行的二进制代码文件。
4. 生成可执行文件
$ gcc hello.o -o hello
总结版:
对应以上四个阶段,直接一个命令
gcc hello.c -o hello
最后阶段
5. 运行及结果
$ ./hello
Better goal, Better life!
一以下是C程序一般的编译过程:
从图中看到:
将编写的一个c程序(源代码 )转换成可以在硬件上运行的程序(可执行代码 ),需要进行编译阶段 和链接这两个阶段。
其中,
1. 编译阶段先通过“编译器 “把一个 .c/ .cpp 源代码 编译成 .s的汇编代码 ;再经过“汇编器 ”把这个.s的汇编代码汇编成 .o的目标代码
2. “连接器 “通过连接其他 .o 代码(如果需要的话)库文件和1中的.o目标代码生成可执行文件
该文件流被这三种程序(红色)的加工,分别表现出四种形式(蓝色),这就是c程序的编译和链接过程。如果再详细的话,编译器在将源文件编译成汇编文件的过程又分为:预处理阶段(生成 .i代码)和 优化阶段