前言
我们在写完代码运行时会发现生成了一个.exe的可执行程序,那么该程序是如何形成的呢?本次章节将在linux下用编译器gcc进行一步步的讲解。通过本次章节的学习,将会掌握linux中的编译器gcc/g++的用法,以及源文件到可执行程序形成的相关知识。
程序的翻译
预处理(gcc -E)
首先.c源文件经过的第一个阶段便是预处理阶段,在该阶段,主要会完成以下几件事:头文件的展开,条件的编译、宏的替换以及注释的去除,我们可以使用gcc -E 源文件 -o 指定目标文件(这里一般生成的是以.i结尾的文件)的命令来生成我们想要的目标文件。
gcc -E:从现在开始,进行程序的翻译,直到预处理完成后停止
-o:后面紧跟自己想要生成的指定目标文件(即给默认生成的文件重命名,便于观察)
编译(gcc -S)
第二个阶段为程序的编译,该阶段主要是将C语言转化为汇编语言,我们可以使用gcc -S 指令来生成编译阶段产生的目标文件,该阶段生成的目标文件后缀为.s
gcc -S:从现在开始进行程序的翻译,到编译阶段完成后停止
汇编(gcc -c)
第三阶段为汇编阶段,在该阶段主要是将汇编语言转化为可重定位二进制目标文件(.obj),我们可以使用指令gcc -c 来进行生成汇编阶段产生的目标文件,该目标文件的后缀为.o
gcc -c:程序进行翻译,进行到汇编完成后停止
链接
该阶段会通过链接器将生成的可重定位二进制目标文件和库文件形成某种合并,形成可执行程序。至此,
.c源文件经过翻译后形成了可执行文件。
(gcc不加选项,直接gcc 源文件 -o 目标文件 会直接形成最终的可执行程序,一般使用gcc编译c语言,g++编译c++语言,用法相通)
扩展选项(gcc/g++)
-E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S 编译到汇编语言不进行汇编和链接
-c 编译到目标代码
-o 文件输出到 文件
-static 此选项对生成的文件采用静态链接
-g 生成调试信息。GNU 调试器可利用该信息。
-shared 此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库.
-O0
-O1
-O2
-O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
-w 不生成任何警告信息。
-Wall 生成所有警告信息。