【Linux】gcc的使用和原理讲解

1. gcc如何完成

gcc指令的格式

gcc [选项] 要编译的源文件 [选项] 目标文件 

2. 预处理(进行宏替换)

预处理需要完成的工作:1. 去注释 2. 头文件展开 3.条件编译4.宏替换
**预处理阶段gcc的命令格式:

gcc -E mycode.c -o mycode.i

其中mycode.c是你需要编译的源文件,mycode.i是预处理完的目标文件。
这里有一个选项:-E
代表着告诉gcc,从现在开始进行程序翻译工作,将预处理工作做完就停下来,不要往后走了。
-o :指目标文件
"i"文件 :表示已经经过预处理的C原始程序。
在这里插入图片描述
左边的部分为我们的源文件mycode.c,右边是经过预处理之后的目标文件mycode.i.
通过左右两边的对比,我们可以发现有以下变化:

  1. 注释去除了
  2. 头文件展开了
  3. 条件编译的结果出来了
  4. 宏被替换了
    通过这些,我们验证了之前所说的预处理阶段完成的工作。

问题:我们为什么可以在windows或者linux上进行C/C++或者其他形式的开发呢?
我们的系统中一定要提前或者后续安装上C/C++相关的头文件,C/C++开发环境不仅仅指的是vs、gcc、g++,更重要的是语言本身的头文件。
那么gcc中C/C++相关的头文件安装在哪里呢?
在这里插入图片描述
在**usr/include*里面,这里可以查看到我们的头文件。

同理,其实在安装vs2019或者vs2022的时候,还选择了对应C的头文件和库文件,所以C的头文件和库文件也存在windows上!

3. 编译(生成汇编)

编译就是生成汇编,将代码转化为汇编语言。

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。

编译的指令为:

gcc -S mycode.i -o mycode.s

这个指令的意思是,从现在开始进行程序的编译工作,完成之后就停止,不要往后走了!

4. 汇编(生成机器可识别代码)

汇编阶段是把编译阶段生成的.s文件转为目标文件。

编译的指令为:

gcc -c mycode.s -o mycode.o

这句指令的意思是:从现在开始进行程序的编译工作, 将汇编工作做完就停下来,不要往后走了。

.o文件:可重定位二进制文件,简称目标文件,虽然已经是二进制了, 但是不可以独立执行,必须要经过链接之后才能执行。

它是有可执行的权限,没有可执行的能力! - - - - 就好像,你有考清华的权限,但是你没有考清华的能力一样,清华的大门永远为你敞开。)悲

查看生成的汇编:
在这里插入图片描述
全是乱码,这是因为vim是一个文本编辑器,它不支持查看。

想要查看的话,可以通过od命令查看:
在这里插入图片描述

od mycode.o

查看到的内容:

5. 连接(生成可执行文件或库文件)

在成功编译之后就进入链接阶段。
链接的指令为:

gcc mycode.o -o mytest
//gcc -o文件 -o 自己命名的文件名

原理上你可以将文件名命名为任何名字,但是我推荐就使用mytest。

6. 函数库

问题:我们的C程序中,并没有定义“printf”的函数实现,且在预编译中包含的“stdio.h”中也只有该函数的声明,而没有定义函数的实现,那么,是在哪里实“printf”函数的呢?

答案:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定时,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。
在这里插入图片描述
静态库:静态库是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为“.a。

动态库:动态库与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”,如前面所述的 libc.so.6 就是动态库。
在这里插入图片描述

想要静态库链接,就在gcc编译的时候,在最后加上-static,这样就是静态链接了,使用了静态库

这里涉及几个扩展的知识:

  1. 如果没有静态库,但是我们就是要使用-static,可以吗? - - - 不行
  2. 如果我们没有动态库,只有静态库,并且gcc能找到静态库,可以编译吗? - - - 可以,gcc默认优先动态链接。 -static的本质:改变优先级,
  3. 我们的可执行程序,不一定是纯的全部动态链接或者全部静态链接,是混合的。

在这里插入图片描述

在讲完动静态库的同时,可以了解一下debug和release:debug比release大一些,原因是debug版本可以被追踪和调试,形成可执行程序的时候,添加了debug信息。

  • 16
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值