深入篇【Linux】学习必备:谈gcc/g++使用及原理 + 动静态库介绍 + debug与release模式

news2024/11/23 9:59:00

深入篇【Linux】学习必备:谈gcc/g++是如何完成程序的翻译过程&&动静态库介绍&&debug与release模式

  • Ⅰ.gcc/g++是如何完成程序的翻译过程的?
    • ①.预处理(宏替换)
    • ②.编译(生成汇编)
    • ③.汇编(生成机器可识别代码)
    • ④.链接(生成可执行文件)
  • Ⅱ.动态库与静态库
    • ①.动态链接
    • ②.静态链接
    • ③.总结:
  • Ⅲ.debug模式与release模式

Ⅰ.gcc/g++是如何完成程序的翻译过程的?

在Linux中使用gcc进行编译使用格式:

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

2.gcc[选项]  要编译的文件

第二种方式直接生成可执行文件a.out
第一种方式可以生成可执行文件并且可重命名。

在这里插入图片描述
要完成程序的翻译要经过4个过程:预处理,编译,汇编,链接。

①.预处理(宏替换)

1.预处理阶段主要功能是头文件展开,宏替换,去注释,条件编译。
2.预处理指令是以#为开头的命令
3.可以通过选项-E来查看预处理阶段的情况,选项-E的功能就是让程序在完成预处理后就停止,不要再进行编译了。
4.实例:gcc -E test.c -o test.i
5.选项-o是指生成目标文件,最后生成一个.i文件。

在这里插入图片描述

②.编译(生成汇编)

1.编译阶段,gcc首先会检查代码的规范性,语法是否有错误,待检查完毕,会将test.i文件中的代码转化为汇编语言。
2.可以通过选项-S来查看编译阶段的情况,选项-S的功能就是让程序在完成编译阶段后就停止,不要再进行汇编了。
3.实例:gcc -S test.i -o test.s
4.选项-o生成目标文件,最后生成一个.o文件

在这里插入图片描述

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

1.汇编阶段,gcc会将汇编语言转化为二进制机器语言。最后会将’.s’文件转化生成一个’.o’目标文件
2.可以通过选项-c来查看汇编代码已转化成二进制目标代码。
3.实例:gcc -c test.s -o test.o
4.最终生成一个可重定位目标二进制文件,简称目标文件。

在这里插入图片描述

④.链接(生成可执行文件)

1.链接阶段主要功能是将目标文件链接生成可执行文件。
2.实例:gcc test.o -o test
3.最终生成了可执行文件test

在这里插入图片描述

你们知道printf函数是怎么使用的呢?函数的使用需要什么呢?
printf函数的使用分为三部分,第一部分就是函数声明,第二部分就是函数功能的实现,第三部分就是函数的调用了。
第一部分和第三部分我们都已经实现了,函数声明在头文件里,而预编译阶段就将头文件展开了,所以函数的声明自然有了,而在我们的代码中直接调用printf函数也实现了,那么问题来了,第二部分在哪实现的呢?
其实在链接过程中,链接的其实就是库。库里给我们提供各种函数方法的实现。

在这里插入图片描述
所以,头文件提供方法的声明+库文件提供的方法的实现+你的代码=你的软件。
而库文件又分为动态库和静态库,进而链接阶段又有动态链接和静态链接。

Ⅱ.动态库与静态库

问题:在C程序中我们在使用printf函数时,并没有定义函数的实现,而在预处理阶段只是将头文件展开,头文件里也只是有函数的声明,并没有函数的定义。那么到底是在哪里定义printf函数的呢?
答案:系统把这些函数的实现都放到名为lib.so.6的库文件中去了。在没有特别指定时,gcc会默认到/usr/lib路径下进行查找,也就是会链接到lib.so.6这个库文件。从而可以实现printf函数了。而链接过程就是将目标文件和库文件进行链接生成可执行程序。

其实库本质上就是一个源文件,经过一定翻译,只给提供一个文件即可,不用给你提供太多的源文件,也可以达到隐藏源文件的目的。它是有路径的。
库也有自己的命名规则,动态库的命名规则一般是:lib name.so.xxx
并且我们的机器上一般只有动态库,没有静态库,需要自己下载静态库。

下载C++的静态库
sudo yum intsall -y libstdc++-static
下载C的静态库
sudo yum install -y glibc-static

那我们的目标文件是如何跟库链接的呢?
链接过程又分为动态链接和静态链接。

①.动态链接

动态链接是指在链接过程中,没有将库文件中的代码拷贝到可执行文件中,而是在程序执行时由运行时链接文件加载库,也就是跳转到动态库文件里,然后再出来。这样可以减少系统开销。动态库一般后缀为.so 前面的lib.so.6就是动态库。gcc在链接时,会自动默认链接动态库,也就是进行动态链接。
1.动态库又称为共享库,每个可执行文件都可以使用。
2.动态库是不能缺失的,一旦对应的动态库缺失,就无法链接了,不仅这个可执行文件无法链接,其他可执行文件都无法链接了。
3.ldd命令可以查看生成的可执行程序是依赖动态库还是静态库的。

在这里插入图片描述
4.file命令可以查看生成的可执行程序是动态链接还是静态链接
在这里插入图片描述

②.静态链接

静态链接指在链接过程中,将静态库中的代码全部拷贝到可执行文件中,所以生成的文件比较大,但在运行时就不再需要库文件了。其后缀一般为’.a’
1.编译器在使用京要哭进行静态链接时,会将自己的方法拷贝到可执行文件中,然后改文件就不需要再依赖库文件了,可以随意执行起来。
2.在Linux中如果想要让程序进行静态链接,需要在链接过程后面加上-static
实例:gcc test.o -o test_static -static

在这里插入图片描述
3.ldd命令可以查看生成的可执行程序是依赖动态库还是静态库的。
在这里插入图片描述
4.file命令可以查看生成的可执行程序是动态链接还是静态链接
在这里插入图片描述
5.静态链接生成的可执行文件要比动态链接生成的可执行文件大,因为静态链接过程中,静态库将方法拷贝到可执行文件中,增大了文件的大小。
在这里插入图片描述
6.如果没有静态库,在链接过程后面加-static。这样是不行的。
7.如果没有动态库,但有静态库,并且gcc可以找到。那么当我们进行连接时,gcc默认会先链接动态库,但没有动态库,所以只能链接静态库。所以我们可以发现选项-static是改变了链接的优先级。
8.一个程序不一定全部都是静态链接或动态链接的。通常是混合链接。

③.总结:

动态库和静态库各有什么优缺点呢?
1.动态库:
优点】动态库因为是共享库,可以有效的节省资源(节省磁盘空间,节省内存空间,节省网络空间)。
缺点】动态库一旦缺失,会导致其他程序无法正常运行。
2.静态库:
优点】静态库可以使程序执行时不依赖库,程序可以独立运行。
缺点】生成的可执行文件体积太大,消耗资源。

Ⅲ.debug模式与release模式

1.程序的发布有两种方式,一种是debug模式,一种是release模式。
2.Linux gcc/g++生成的可执行程序默认是release默认。
3.debug模式发布的程序是可以追踪调试的。
4.要想以debug模式发布程序需要在生成可执行程序时在后面加上-g选项。

5.【问题】为什么debug模式发布的程序是可以追踪调试的? 因为在形成可执行程序时候,程序中添加了debug信息。 那么我们可以知道,debug模式发布的程序的大小一定会比release模式发布的程序大小要大,因为要包含debug信息。
在这里插入图片描述
6.readelf -S 是用来读取可执行程序中二进制的构成的。我们可以用该命令来查看添加的debug信息
在这里插入图片描述

利用管道来查找test_debug可执行程序中的含debug的信息
readelf -S test_debug |grep -i debug

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/667686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装Nginx网站服务

目录 前言 一、Nginx简介 二、Nginx应用场景 三、Nginx与Apache优缺点 1)Nginx 相对于 Apache 的优点 2)Apache 相对于 Nginx 的优点 3)Nginx和Apache的差异 四、阻塞与非阻塞、同步与异步 五、安装Nginx软件 1、在线安装 ①使用y…

半导体测试系统 芯片自动化测试软件 可定制测试方案ATECLOUD-IC

*测试产品:芯片半导体器件。纳米软件ATECLOUD-IC芯片自动化测试系统适用于二极管、三极管、绝缘栅型场效应管、结型场效应管、单向和双向可控硅、普通和高速光耦、整流桥、共阴共阳二极管及多阵列器件等各类半导体分立器件综合性能自动化测试。 *被测项目&#xff…

vue3 script setup

解决在使用vue 3 composition API(组合式API)时繁琐的问题,比如定义一个方法,模板需要使用该方法,就必须将方法返回,当组件中存在大量方法和属性时就很麻烦。 一、什么是script setup 二、script setup什么作用 1.自动注册子组件 …

flutter 主题色彩管理组件 flex_color_scheme

flutter 主题色彩管理组件 flex_color_scheme 前言 原文 https://ducafecat.com/blog/flutter-flex-color-scheme 平时我们做样式适配关心几个方面: 设计稿颜色 标记尺寸大小、比例 全局修改为主 快速可修改 今天将会介绍一个快速调整主题色彩样式的三方组件 flex_color_schem…

[RocketMQ] NameServer启动流程源码解析 (一)

文章目录 1.NameServer概述2.NamesrvStartup启动入口3.createNamesrvController创建NamesrvController3.1 创建NamesrvController 4.start启动NamesrvController4.1 初始化NettyServer4.1.1 创建NettyRemotingServer4.1.2 registerProcessor注册默认请求处理器4.1.3 启动定时任…

Google C++ Style文档及常用代码规范(一):命名约定、格式、注释

文章目录 Google C Style文档及常用代码规范(一):命名约定、格式、注释命名约定通用命名规则文件命名类型命名变量命名常量命名函数命名命名空间命名枚举命名宏命名命名规则的特例 格式注释注释风格文件注释类注释函数注释变量注释类数据成员…

flutter getx nested navigation 嵌套路由

flutter getx nested navigation 嵌套路由 视频 https://youtu.be/SXER4JVBFps 前言 嵌套路由可以用在如购物确认向导界面切换。 使用 getx 实现嵌套路由,需要如下步骤: 通过 Navigator 组件的 key 属性 用 Get.nestedKey(1) 进行标记 onGenerateRoute…

delmia msd学习

在默认打开的结构树中添加一个产品tworobts TwoRobots是新建的一个空产品,并将其插入到resoourceslist下面通过 然后创建一个工位的工作区域 插入机器人 把机器人放在工作区域中,即其子物体 先选要移动的对象,然后选移动到什么地方 Keep positions的意思…

栈的概念和结构以及实现

1. 栈 1.1栈的概念及结构 栈:一种特殊的线性表,其只允许在 固定的一端 进行 插入和删除 元素操作。 进行数据插入和删除 操作的一端称为 栈顶 ,另一端称为 栈底 。栈中的数据元素遵守 后进先出 LIFO (Last in First Out) 的原则。 压栈:栈的插入操作叫做…

【带你刷《剑指Offer》系列】【每天40分钟,跟我一起用50天刷完 (剑指Offer)】第一天

专注 效率 记忆 预习 笔记 复习 做题 欢迎观看我的博客,如有问题交流,欢迎评论区留言,一定尽快回复!(大家可以去看我的专栏,是所有文章的目录)   文章字体风格: 红色文字表示&#…

python:使用Scikit-image对单波段遥感影像进行形状特征提取(morphology)

作者:CSDN @ _养乐多_ 本文将介绍使用Scikit-image对单波段遥感影像做形状特征提取的方法和代码。包括:腐蚀(erosion),膨胀(dilation),开运算(opening),闭运算(closing),形态学梯度(morphological gradient),白帽变换(top hat),黑帽变换(black hat),形…

一、枚举类型——用EnumSet来代替标识

Set 是一种不允许有重复元素存在的集合。enum 要求每个内部成员都是唯一的,因此看起来很像 Set,但是由于无法添加或移除元素,它并不如 Set 那么好用。于是 EnumSet 被引入,用来配合 enum 的使用,以替代传统的基于 int …

计算机启动

按下主机上的 power 键后,第一个运行的软件是 BIOS,BIOS 全称叫 Base Input & Output System,即基本输入输出系统。 (8086的1MB内存) 地址 0~0x9FFFF 处是 DRAM,顶部的 0xF0000~0xFFFFF&am…

第一章 基础算法(一)—— 快排,归并与二分

文章目录 快排归并排序二分整数二分浮点数二分 快速排序练习题785. 快速排序786. 第k个数 归并排序练习题787. 归并排序788. 逆序对的数量 二分练习题789. 数的范围790. 数的三次方根 有些累了,把这两天做的笔记整理发出 快排 快排的思路: 确定分界点根…

Pandas-DataFrame常用基础知识点总结

注:以下知识点总结是将数据转为DataFrame格式数据的基础之上进行操作的 (首先需要做的是将数据转为DataFrame格式) DataFrame格式示例: import pandas as pd data {"code": [000008, 000009, 000021, 000027, 00003…

代码随想录二刷 day28 | 回溯 之 93.复原IP地址 78.子集 90.子集II

day28 93.复原IP地址判断子串是否合法 78.子集回溯三部曲 90.子集II 93.复原IP地址 题目链接 解题思路: 切割问题就可以使用回溯搜索法把所有可能性搜出来 回溯三部曲 递归参数 startIndex一定是需要的,因为不能重复分割,记录下一层递归分…

一种数据源切换的实践方案

随着业务的不断深入,我们会碰见很多关于数据源切换的业务场景,数据源切换也是当前最常用的分库后的分流策略方式之一,对于读写职责分离的数据库集群而言,我们在服务层面制定相应的接口与数据库交互的定制化开发,也就是…

云 cloud 高可用系统--在RDS上实现,从原理上不可能保证你100%不丢数据

我写这篇文字,实属无奈,在目前很多企业都依赖云的情况下,数据库的很多事情都是身不由己,发生问题,你查看日志,分析日志可能你连日志都不是全部的,并且想通过程序来过滤这个日志很多情况下都有限…

数据库系统概述——第六章 关系数据理论(知识点复习+练习题)

🌟博主:命运之光 🦄专栏:离散数学考前复习(知识点题) 🍓专栏:概率论期末速成(一套卷) 🐳专栏:数字电路考前复习 🦚专栏&am…

CMU 15-445 Project #2 - B+Tree(CHECKPOINT #1)

CHECKPOINT #1 一、题目链接二、准备工作三、部分实现1.查找操作2.插入操作3.删除操作 四、评测结果 一、题目链接 二、准备工作 见 CMU 15-445 Project #0 - C Primer 中的准备工作。 三、部分实现 对于B树的节点定义,通过节点类的命名 b_plus_tree_page 不难发现…