【Linux】编译器-gcc/g++的使用


一.背景知识

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++同理,这里就不赘述了

猜你喜欢

转载自blog.csdn.net/weixin_63449996/article/details/129940201