【Linux】Linux编译器-g++、gcc、动静态库

 只要积极创造,机遇无时不有;只要善于探索,真理无处不在。💓💓💓

目录

  ✨说在前面

🍋知识点一:Linux编译器-g++、gcc

•🌰1. 背景知识

•🌰2. gcc如何完成

•🌰3. 条件编译的作用

•🌰4. 函数库

 🍇库的定义

 🍇动态库与静态库

 🍇动静态库对比

 🍇验证工作

 🍇技术上理解库

 • ✨SumUp结语


  ✨说在前面

亲爱的读者们大家好!💖💖💖,我们又见面了,上篇文章我们讲解了linux中的重要工具-yum和vim,大家可以回顾一下,加深印象~

我们今天给大家讲解一下Linux中的另外一个重要工具-编译器g++、gcc以及他们在Linux命令中的使用。更重要的是,由编译和链接这部分知识所牵涉出来的动态库、静态库的链接问题。动静态库是很重要的,在后面我们还会进行二次学习,希望大家可以好好学习本篇博客,为以后的学习打下坚实的基础。

   👇👇👇
💘💘💘相关链接如下(直接点击即可)

【Linux】Linux重要工具

 🎉🎉🎉xshell + 云服务器🎉🎉🎉

 博主主页传送门:愿天垂怜的博客

 

 

🍋知识点一:Linux编译器-g++、gcc

•🌰1. 背景知识

对于这一部分内容,需要一些前置的编译链接的相关知识。如果大家忘记了或者对这部分内容还有欠缺,可以看看我的这两篇文章:

【C语言】编译与链接过程详解:从源码到可执行程序,-CSDN博客

【C语言】详解预处理-CSDN博客

•🌰2. gcc如何完成

🍇预处理

预处理功能主要包括宏定义、文件包含、条件编译、去注释等。 预处理指令是以#号开头的代码行。 gcc –E hello.c –o hello.i 选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。 选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。

我们可以看到.i为后缀的文件处理了宏、条件编译,并且展开了头文件,所以main函数所在的位置是841行,而上面都是头文件的内容。 

 🍇编译

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。 

  🍇汇编

汇编阶段是把编译阶段生成的“.s”文件转成目标文件,读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了。

注意:以.o为后缀的文件称为二进制可重定位目标文件

🍇链接

在编译代码的过程中,我们通常将多个.c文件编译形成.o文件,然后结合链接库一起打包形成可执行文件,而对于.i、.s为后缀的文件在编译过程中不会正在形成。

 举例如下:

•🌰3. 条件编译的作用

从大家从学习面向过程语言开始,就学习了条件编译。那么大家当时是否疑惑,为什么要有条件编译,条件编译究竟有什么作用呢?

我们利用上节课学习的vim写出下面代码:

 这份代码相信大家都能看懂,由于定义M被注释了,所以应该会输出 professional version(专业版)。但是注意,在编译的过程中,我们可以加上宏定义的指令,如下

 因此,条件编译有什么意义呢?我们举出下面三个场景:

scene1:如上,软件对专业度、收费情况进行区分(业务),使用条件编译,可以进行代码动态裁剪。

scene2:内核源代码也是采用条件编译进行动态裁剪。

scene3:开发工具,应用软件。

 

•🌰4. 函数库

 🍇库的定义

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

答案是:系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了,在没有特别指定,gcc 会到系统默认的搜索路径“/usr/lib”下进行查找,也就是链接到 libc.so.6 库函数中去,这样就能实现函数“printf”了,而这也就是链接的作用。

定义库是一套方法或数据集,为我们的开发提供最基本的保证(基本接口、功能,加速我们二次开发)

 🍇动态库与静态库

1. 动态库(.so / .ddl):动态链接既涉及编译时的准备工作(如记录外部符号引用、生成占位符地址等),也涉及运行时的实际链接过程(如加载动态库、解析符号地址等)。程序的编译链接阶段会进行一些相关的设置,以确保程序具备在运行时到动态库中寻找所需方法的能力。

 我们可以用一个例子来理解动态库链接的过程。

假设你初中刚毕业,看到了高中的课表,其中计划下午13:00进行上网,但是不知道在哪里上网,于是你询问学长得知在学校东门左100米处有一个XX网吧,可以在这个地方上网。

 在这个例子中,初中刚毕业,是在上高中之前通过询问学长的方式得到上网的地址,而高中就相当于程序,当上高中之后,我直接根据之前询问学长所得知的网吧地址直接去就行了,这就是动态链接在运行时的实际链接过程。

注意:动态库被多个程序共享,一旦缺失,会导致所有程序无法执行!

2. 静态库(.a / .lib):程序在编译链接的时候将库的代码连接到可执行文件中,程序运行的时候将不再需要静态库。

我们依然继续刚才的例子,学校发现了很多学生都喜欢在网吧打游戏,这对学生的成绩造成了很大的影响,所以学校取缔了这个网吧,于是你中午没上网,导致你不想听下午的课程了,这就对应了动态库的不可缺失性。

但是你就是想完成这样一个过程,于是你找到了这个网吧的老板,要求在电脑仓库中拿出进而我之前上网的机子同款的机子买下来,然后带到学校去进行操作,这就是静态链接。静态链接会将静态库中对应函数的方法直接拷贝给我自己,因此会造成静态链接的程序体积很大。

注意:静态链接只有在链接的时候有用,一旦形成可执行程序,该程序可以不再需要此静态库。

 🍇动静态库对比

1. 链接动态库形成的可执行程序一定很小。

2. 可执行程序对静态库的依赖小,而动态库不能缺失。

3. 程序运行,需要加载到内存。如果是静态链接,会导致内存中出现大量重复代码,浪费资源。

4. 动态链接比较节省内存和磁盘资源。

 🍇验证工作

1. 我们可以在 /usr/lib64 目录下查看系统的库:


 

 2. 我们可以用 ldd 命令查看该文件依赖哪些动态库:

而 libc.so 就是C语言的标准库,包含了多种C函数方法的实现。

3. 我们可以通过在选项后面增加 -static 来强制静态链接:

注意:C++和C在库的链接上是一样的,唯一的不同是C的编译器使用的是gcc,而C++使用的工具是g++,大家可以敲一敲键盘自行体验C++的工静态库链接过程。

 🍇技术上理解库

我们知道,在编译的过程中,我们会将一份或多份的.c文件转换成.o文件再和库进行链接。假设我们希望提供被人程序以及方法的声明,而不希望方法的实现被看到,我们应该怎么操作呢?

我们先写一份代码:

我们希望在 code1.h 中声明 func1 ,在 code1.c 中实现 func1,func2 同理,那么我们新创建一个 lib 目录,在该目录下进行操作:

 完成code1和code2相应内容代码:

 ​​​​​

 我们可以将 lib 保留,将备份文件拷贝出去:

接着,我们先将.c文件编译,然后我们就可以将含有 func1 和 func2 的.c文件删除了:

接下来我们直接链接.o文件,得到可执行程序:

这样,我们就像别人隐藏了主函数中特定接口的实现了。

其实,借助这个示例,我想表达的是,所谓库,本质也是许许多多个.o文件构成的。我们写的代码编译成.o后,和库链接,其实就是链接这些.o文件。

    

 • ✨SumUp结语

到这里本篇文章的内容就结束了,本节给大家讲解了Linux的又一类重要工具-编译器。大家可以将我文章中写的操作自己实操一遍。加深印象。希望大家能够认真学习,迎接接下来的挑战,期待大家继续捧场~💖💖💖

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring整合Mybatis、junit纯注解

如何创建一个Spring项目 错误问题 不知道什么原因,大概是依赖版本不兼容、java版本不对的问题,折磨了好久就是搞不成。 主要原因看pom.xml配置 pom.xml配置 java版本 由于是跟着22年黑马视频做的,java版本换成了jdk-11,用21以…

【架构面试】二、消息队列和MySQL和Redis

MQ MQ消息中间件 问题引出与MQ作用 常见面试问题:面试官常针对项目中使用MQ技术的候选人提问,如如何确保消息不丢失,该问题可考察候选人技术能力。MQ应用场景及作用:以京东系统下单扣减京豆为例,MQ用于交易服和京豆服…

MATLAB提供的颜色映射表colormap——伪彩色

图像处理领域的一个习惯:不是真实的颜色,一般用伪彩色。一是说明不是物体本身的颜色,二是彩色更容易分辨。 MATLAB陆续提供了16种颜色映射表colormap。 之前的都很丑,近5年新增的4种还可以。总的说来还是丑。 这是一种鸟的名字。…

案例研究丨浪潮云洲通过DataEase推进多维度数据可视化建设

浪潮云洲工业互联网有限公司(以下简称为“浪潮云洲”)成立于2018年,定位于工业数字基础设施建设商、具有国际影响力的工业互联网平台运营商、生产性互联网头部服务商。截至目前,浪潮云洲工业互联网平台连续五年入选跨行业跨领域工…

电脑无法开机,重装系统后没有驱动且驱动安装失败

电脑无法开机,重装系统后没有驱动且驱动安装失败 前几天电脑突然坏了,电脑卡住后,强制关机,再开机后开机马上就关机。尝试无数次开机后失败,进入BIOS界面,发现已经没有Windows系统了。重新安装系统后&…

C++异步future

🌎 C11异步futrue 文章目录: C11异步futrue future介绍     应用场景     future操作       std::async函数模版       std::packaged_task类模版       std::promise类模版 🚀future介绍 std::future是C11标准库…

【C++探索之路】STL---string

走进C的世界,也意味着我们对编程世界的认知达到另一个维度,如果你学习过C语言,那你绝对会有不一般的收获,感受到C所带来的码云风暴~ ---------------------------------------begin--------------------------------------- 什么是…

CF 339A.Helpful Maths(Java实现)

题目分析 输入一串式子,输出从小到大排列的式子 思路分析 如上所说核心思路,但是我要使用笨方法,输入一串式子用split分割开,但是此时需要用到转义字符,即函数内参数不能直接使用“”,而是“\\”。分割开后…

C#,入门教程(07)——软件项目的源文件与目录结构

上一篇: C#,入门教程(06)——解决方案资源管理器,代码文件与文件夹的管理工具https://blog.csdn.net/beijinghorn/article/details/124895033 创建新的 C# 项目后, Visual Studio 会自动创建一系列的目录与文件。 程序员后面的工…

Cpp::静态 动态的类型转换全解析(36)

文章目录 前言一、C语言中的类型转换二、为什么C会有四种类型转换?内置类型 -> 自定义类型自定义类型 -> 内置类型自定义类型 -> 自定义类型隐式类型转换的坑 三、C强制类型转换static_castreinterpret_castconst_castdynamic_cast 四、RTTI总结 前言 Hell…

Android中Service在新进程中的启动流程

目录 1、Service与AMS交互框架介绍 1.1、认识AMS代表IActivityManager 1.2、认识客户端代表IApplicationThread 2、Service启动流程概览 我们知道Android有四大组件,Activity、Service、ContentProvider、Broadcast,每个组件在系统运行中或者我们编写…

docker 简要笔记

文章目录 一、前提内容1、docker 环境准备2、docker-compose 环境准备3、流程说明 二、打包 docker 镜像1、基础镜像2、国内镜像源3、基础的dockerfile4、打包镜像 四、构建运行1、docker 部分2、docker-compose 部分2.1、构建docker-compose.yml2.1.1、同目录构建2.1.2、利用镜…

利用Redis实现数据缓存

目录 1 为啥要缓存捏? 2 基本流程(以查询商铺信息为例) 3 实现数据库与缓存双写一致 3.1 内存淘汰 3.2 超时剔除(半自动) 3.3 主动更新(手动) 3.3.1 双写方案 3.3.2 读写穿透方案 3.3.…

活动回顾和预告|微软开发者社区 Code Without Barriers 上海站首场活动成功举办!

Code Without Barriers 上海活动回顾 Code Without Barriers:AI & DATA 深入探索人工智能与数据如何变革行业 2025年1月16日,微软开发者社区 Code Without Barriers (CWB)携手 She Rewires 她原力在大中华区的首场活动“AI &…

python爬虫入门(一) - requests库与re库,一个简单的爬虫程序

目录 web请求与requests库 1. web请求 1.1 客户端渲染与服务端渲染 1.2 抓包 1.3 HTTP状态代码 2. requests库 2.1 requests模块的下载 2.2 发送请求头与请求参数 2.3 GET请求与POST请求 GET请求的例子: POST请求的例子: 3. 案例:…

全连接神经网络(前馈神经网络)

目录 一、初步认识全连接神经网络 1、神经元 2、网络结构 3、正向传播算法 二、反向传播算法 1、理解 2、迭代流程 三、构建神经网络模型的基本步骤 四、线性回归神经网络结构 4.1 数据处理 1、数据导入 2、数据归一化处理 3、数据集划分 4、数据形状变换 4.2 模…

【C++初阶】第11课—vector

文章目录 1. 认识vector2. vector的遍历3. vector的构造4. vector常用的接口5. vector的容量6. vector的元素访问7. vector的修改8. vector<vector\<int\>>的使用9. vector的使用10. 模拟实现vector11. 迭代器失效11.1 insert插入数据内部迭代器失效11.2 insert插入…

Linux查看服务器的内外网地址

目录&#xff1a; 1、内网地址2、外网地址3、ping时显示地址与真实不一致 1、内网地址 ifconfig2、外网地址 curl ifconfig.me3、ping时显示地址与真实不一致 原因是dns缓存导致的&#xff0c;ping这种方法也是不准确的&#xff0c;有弊端不建议使用&#xff0c;只适用于测试…

PAT甲级-1024 Palindromic Number

题目 题目大意 一个非回文数&#xff0c;加上它的翻转数所得的和&#xff0c;进行k次&#xff0c;有可能会得到一个回文数。给出一个数n&#xff0c;限制相加次数为k次&#xff0c;如果小于k次就得到回文数&#xff0c;那么输出该回文数和相加的次数&#xff1b;如果进行k次还…

xss靶场

xss-labs下载地址&#xff1a;GitHub - do0dl3/xss-labs: xss 跨站漏洞平台 xss常见触发标签&#xff1a;XSS跨站脚本攻击实例与防御策略-CSDN博客 level-1 首先查看网页的源代码发现get传参的name的值test插入了html里头&#xff0c;还回显了payload的长度。 <!DOCTYPE …