Linux编译四组件(二):gcc篇

481 阅读5分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


通过前几篇博客的学习,相信大家已经对Linux系统有了一个初步的认知和了解,那么本篇博客就对所学内容进行有机整合,进入Linux系统编程的阶段.

  • 前面讲过在Linux环境下进行编程需要以下 4 个工具:
  1. 代码编辑器 vim
  2. 编译器 gcc
  3. 调试器 gdb
  4. 工程管理工具 Makefile

vim已经有专门一篇博客讲过它的用法与内容了,所以这次主要介绍gcc,看看他们究竟是通过怎样的操作实现编程的.

   [ 这里演示的编程操作以C语言为例 ]

整体步骤

1. 创建文件

输入指令创建 :

vim hello.c	

注: hello.c是你希望创建文件的文件名

2. 键入代码

hello.c文件中i进入插入模式,输入好程序代码esc , :wq保存退出

  • 注: 这里不能像在Windows系统中一样,为了使打印结果不一闪而逝加入的system("pause");这一语句,因为Linux系统中不支持.

3. 编译

通过gcc + 目标编译文件名,完成对其的编译,正常编译完成没有反馈

  这里编译成功之后,我们可以额外的通过ll先查看一下编译产生的文件, 我们可以看到,这个a.out文件就是默认编译产生的文件

4. 执行

通过相对路径方式执行这个a.out文件,打印结果就顺利显示在界面上了:

./a.out

如果你完成了上述操作,恭喜完成了第一次Linux系统环境下的编程. 有了第一次成功,相信以后多样的代码都可以在Linux环境下顺利执行


接下来,我们深层次地理解一下编程过程中的这些工具与文件:

  • a.out是什么?  我们通过指令file a.out详细查看一下这个文件:

通过结果我们大致可以得知:   

它是一个Linux下的标准ELF格式文件,并且executable说明它是一个可执行文件,所以我们才可以通过./的方式直接执行它

  • 为什么名为a.out,可以有其他名称吗? 我们可以在gcc指令编译时就设置好 输出文件的文件名,如下:
gcc hello.c  -o  hello

-o意为- output,后面接 希望输出文件修改的文件名   我们ls罗列了一下文件夹中的文件,发现确实是通过指令进行了名称修改

用了这么多次的gcc到底是什么?


gcc

它是一个编译器 GCC 原名为 GNU C 语言编译器(GNU C Compiler),因为它原本只能处理 C语言

现已被大多数类Unix操作系统(如LinuxBSDMac OS X等)采纳为标准的编译器,GCC同样适用于微软的Windows. GCC 通过快速扩展,变得可处理 C++。后来又扩展能够支持更多编程语言,如FortranPascalObjective-CJavaAdaGo以及各类处理器架构上的汇编语言等

通过gcc我们可以把编译过程拆解开

● 编译的四个最核心的步骤/整体过程:

  1. ==预处理== a). 宏替换   相当于文本替换,相当于字符串的复制粘贴.   如果在程序首部#define SIZE 8,就会将整个文件中的SIZE在预处理阶段全部替换为8

b). 去注释   对部分代码进行解释的注释是没有必要编译的,它仅供提高代码可读性

c). 条件编译    避免重复编译,提高代码效率  

d). 替换头文件     将包含的头文件复制引入函数,包括运用到的函数/模块等等    

输入指令:

gcc -E  hello.c  -o  hello.i				//大写E
  • -E是预处理指令
  • hello.i就是对于源文件预处理产生的文件

回车之后没有反馈,我们vim查看一下这个hello.i文件内部

里面相比于之前寥寥几行的代码主体多出了很多行代码,其实这个就是对头文件进行了替换 这里当时的SIZE也直接变成了8,说明确实是在编译之前就进行了文本替换,一个头文件、宏的展开会产生大量的代码。

  1. 编译 【将c语言代码文件变成汇编代码,也是高级语言向机器语言过渡的一个中间环节】   输入指令:
gcc -S  hello.i  -o  hello.s				//大写S

hello.s文件保存了我们代码的汇编结果,我们再次vim查看内部

我们发现已经有些阅读天书的感觉了,但是仍旧有些字段我们是可读的

  • 注:不同的CPU支持的汇编语句、机器指令是有差别的
  1. 汇编 【将汇编代码变成二进制的机器码】   输入指令:
gcc -c  hello.s  -o  hello.o				//小写s

vim查看,我们发现现在相对于前两次查看是彻底看不懂了,它是二进制的机器语言,大部分人类看不懂,但是机器可以看懂

  1. 链接

【把多个.c文件编译成的机器码进行汇总,比如函数在a中定义,并在b中调用,那么不进行链接就无法正常执行】   输入指令:

gcc  hello.o  -o  hello		

这次终于对前面文件没有依赖了,直接运行指令就可以完成链接

我们一样使用./ + 文件名进行验证,正确执行,说明二者等效。正确打印出我们开头设置的宏定义参数,至此,对编译过程的演示就告一段落了

  • 小结 简单的记忆方法:我们使用的预处理指令顺序为E --> S --> c,相当于esc键,位于键盘左上角的键

这里只是罗列几个常用命令 , 更多gcc指令后缀请客官自行使用man手册查看.