文章目录
一.背景知识
gcc是由GNU开发的编程语言译器,GNU工具链也包含了编译器、汇编器和连接器。一个C/C++文件要经过预处理、编译、汇编和连接才能变成可执行文件,过程如下图所示:
1)预处理:预处理所要完成的有,头文件展开、去注释、宏替换、条件编译。C/C++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”、宏定义命令“#define”、条件编译命令“#if”、“#ifdef”等。预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到.i文件中等待进一步处理。
2)编译:任务是将C代码,即上述的.i文件,翻译成汇编语言。
3)汇编:汇编代码转为二进制目标代码(机器语言),形成.obj的文件。
4)链接:将汇编过程产生的二进制代码进行链接,即上述过程产生的.obj文件和系统库的obj文件链接起来,最终生成了可以在特定平台运行的可执行文件。
二.操作
前言gcc的选项
- -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
- -S 编译到汇编语言不进行汇编和链接
- -c 编译到目标代码
- -o 文件输出到 文件
- -static 此选项对生成的文件采用静态链接
- -g 生成调试信息。GNU 调试器可利用该信息。
- -shared 此选项将尽量使用动态库,所以生成文件比较小
- -O0
- -O1
- -O2
- -O3 编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高
- -w 不生成任何警告信息。
- -Wall 生成所有警告信息。
这篇文章只着重详细解释重要的选项,接下来一起踏入gcc吧!
1.-o 将处理结果输出到指定文件。
接下里我进行演示,首先,我们先touch创建一个测试文件,我暂且将其命名为test.c,然后我们利用vim编辑器命令,编辑文件,我在test.c文件写入了一下代码:vim的使用详解请点击这里
然后我们退出编辑器,OK,从这一步开始我开始讲解如何使用gcc编译器。
我们在命令行输入:gcc test.c -o myfile
或者gcc -o myfile test.c
两种都可以,需要注意的是-o选项后面一定要跟上需要生成的可执行程序的名字(这个可执行程序的名字我们可以按照自己的想法取)。这句代码的意思就是将test.c文件进行编译,生成一个名为myfile的可执行文件。
然后我们输入./myfile,就可以运行程序了,如下:
2.预处理:-E 只进行预处理
-E 只进行预处理,这个不生成文件,你需要把他重定向到一个输出文件里面(否则将把预处理后的结果打印到屏幕上)。
我们在测试文件test.c中写入一下代码:
1 #define M 100 //演示预处理阶段的宏替换
2 #define PRINT //演示预处理阶段的条件编译,注意宏常量不一定需要给值
3
4 #include<stdio.h>
5 int main()
6 {
7 printf("hello world\n");
8 printf("hello world\n");
9 printf("hello world\n");
10 printf("hello world\n");
11 printf("hello world\n");
12
13 //演示预处理阶段的去注释
14 printf("hello world! start\n");
15 //printf("hello world!\n");
16 //printf("hello world!\n");
17 //printf("hello world!\n");
18 printf("hello world! end\n");
19
20
21 #ifdef PRINT
22 printf("hello PRINT\n");
23 #else
24 printf("none\n");
25 #endif
26
27 return 0;
28 }
编译代码:gcc -E test.c -o myfile.i
将预处理后的文件写到myfile.i文件中,得到这个文件之后,我们可以看出这个文件比test.c文件大很多,我们vim查看文件,就可以看到很多代码,这些代码就是预处理完之后的代码,前面的一堆代码就是头文件被展开了,所以myfile.i文件很大,并且我们也可以得出预处理阶段注释被删除了,宏被替换了,条件编译被处理了。
3.编译:-S 只处理到编译。
-S 编译到汇编语言,不进行汇编和链接,即只进行预处理和编译。
在命令行输入gcc -S myfile.i
或者gcc -S myfile.i -o myfile.s
,然后你们vim打开myfile.c文件,就可以一览汇编语言了,可能看到寄存器等操作。
4.汇编:-c 编译到目标代码,生成.o文件
输入:
gcc -c myfile.i -o myfile.o
这是我们目前为止,生成的文件:
注意我们./myfile.o是无法运行的,即便我们’chmod +x myfile.o’,给它加上可执行选项也不行,也就意味着.obj文件是没有办法执行的,不是可执行文件。我们通过vim打开文件,可以看到如下代码:
5.链接
输入:gcc myfile.o
或者gcc myfile.o -o myfile
- 在成功完成以上步骤之后,就进入了链接阶段。链接的主要任务就是将生成的各个.o文件进行链接,生成可执行文件。
- gcc/g++不带-E、-S、-c选项时,就默认生成预处理、编译、汇编、链接全过程后的文件。
- 若不用-o选项指定生成文件的文件名,则默认生成的可执行文件名为a.out。
- 链接后生成的文件也是二进制文件。
三.总结
一般来说,常用的是gcc test.c -o myfile
,直接生成可执行程序myfile,然后./myfile,进行运行。如果你们需要查看预处理,编译,汇编各个阶段的情况,就用上-E -S -c,分别生成.i .s .o为后缀的文件。
g++同理,这里就不赘述了