像VS,Delphi这种集成开发环境(IDE),他们一般把编译和链接的过程一步完成,将这种编译和链接合并到一起的过程叫做构建,构建的英文名是Build,所以你可以看到VS的编译就是这个词
比如一个hello world的小程序,编译过程也是很复杂的,可以分为4步:预处理,编译,汇编,链接
对C语言来说,比如源文件是.c,那他就会把.c以及相关的头文件,全部被预编译器cpp预编译到一个文件里,这个文件是.i文件
源文件是.cpp,那就是到.ii文件
这两个文件其实就是预处理后的文件
预编译过程主要是解决了“#”开始的预编译指令,比如#include, #define这些
经过这些处理后的.i文件不包含宏定义,因为已经被展开了,并且包含的文件也已经被插入到.i文件里
就是把预处理完的文件,经过一系列词法分析,语法分析,语义分析以及优化后生成的相应的汇编代码文件,所以本质上生成的是汇编代码,现代gcc把预编译和编译两个步骤合并为一个,使用一个叫cc1的程序完成这两个步骤,执行完后,会生成汇编文件,hello.s文件
对C语言的话,是cc1
C++是cc1plus
Objective-C是cc1obj
fortran是f771
Java是jc1
实际上gcc这个命令只是这些后台程序的包装,它会根据不同的参数要求去调用预编译编译程序cc1,汇编器as,链接器Id
汇编器是把汇编语言转为机器可以执行的指令,每条汇编语句都对应一个机器指令,所以汇编器的汇编过程相对于编译器来说很简单,没有复杂的语法,也没有语义,也不用指令优化
这个汇编后形成的文件叫做目标文件,是hello.o
为什么不汇编器直接形成可执行文件,而是形成目标文件呢,为什么要链接呢
其实我们需要把一大堆文件也就是.o文件链接起来才可以得到.out文件,就是最终的可执行文件
链接到底起个什么作用呢?