目录
前言:
平时总是在在linux系统上通过gcc编译文件,这里gcc整个编译的过程说明一下,做一下基础知识备份。
编译其实一共分为4步:预处理,编译,汇编,链接。下面我就详细说一下C语言的编译这四步的作用。
首先,我们看一下简单的代码 hello.c 文件,我们通过vim编写即可:
#include <stdio.h>
#define PI 3.14
int main(void){
printf("PI*r*r=%lf\n",PI*3*3);
printf("hello world\n");
return 0;
}
1: 预处理
预处理就是将.c文件中include和#define这些预处理指令合并到一起。
我们通过gcc -E hello.c -o hello.i 命令,可以对文件只进行编译。
生成了一个hello.i文件。打开这个文件,可以看到很长的内容,我们看最后面的内容
预处理完成以后,.i文件的内容是预处理程序将PI的内容直接替换到了我们的c语言中PI。
2: 编译
编译其实简单来说就是将c语言转成汇编语言。我们通过命令gcc -S hello.i 可以完成编译操作。会生成一个hello.s的文件。
我们打开看一下。cat hello.s
会发现这里其实已经是汇编语言了。编译还有一个作用,就是检测你语法错误。
3:汇编
然后我们在对.s文件进行操作,将它专为机器语言。因为我们知道,计算机最后只认识机器语言的。所以,我们执行下面的命令:gcc -c hello.s 会生成 hello.o文件。
这个hello.o文件是机器语言(二进制的文件),所以我们通过cat查看都是乱码。但是,这里的.o虽然已经是二进制文件了,但是仍然不可以运行。
因为二进制文件分为两类:
a) 可执行文件(executable)
b)可重定位文件(relocatable)
我们通过命令:file hello.o查看
可以明确看到文件类型。所以我们还需要最后一步。
4:链接
链接其实就是将我们的二进制文件与系统的运行时的文件库做一个绑定。让该环境下可以执行这个命令。最后会生成.out文件。
我们运行指令 gcc hello.o 会生成a.out文件
然后file a.out查看一下文件类型:
发现这里已经是可以执行的二进制文件了。我们这一次的编译过程完成。
我画了一个简单的图来说明该流程:
结束语
虽然我们平时总是直接gcc ***.c文件,其实都是程序替我们做了很多事儿,但是我觉得还是需要了解一些基本原理,才能更有助于我们的开发工作。