【Linux】软硬链接 | 动静态链接(三)

news2025/3/9 10:49:29

目录

前言:

一、软硬链接

1.软链接

2.硬链接

3.硬链接数

4.软硬链接的区别

5.使用unlink删除链接的文件

6.目录文件链接数( . 和 .. ) 

二、静态库的制作和使用

1.制作静态库

2.使用静态库

2.1方法一

2.2方法二

2.3方法三

三、动态库的制作和使用

1.制作动态库

2.使用动态库

2.1方法一

2.2方法二

2.3方法三 

2.4方法四

四、命令总结

1.关于软硬链接:

2.关于动静态库和连接命令:

3.关于gcc编译器选项

总结:


前言:

嘿嘿,各位如果第一次看到这里会很懵,因为这里并没有从头到尾讲解。了解软硬链接至少要知道文件系统这方面知识,我把他们总结成了文件操作篇,可以去看我前面的文章(相当于文件篇一二三),再来看这篇文章就畅通无阻了(有基础的除外)。

一、软硬链接

1.软链接

软链接本质是一个独立的文件,我们使用以下命令创建软链接:

ln -s 源文件 创建软链接目标文件

大家可以理解为Windows中的创建快捷方式,当时我们删除这个文件的其他相关文件,即使快捷方式存在也无法打开。我们可以理解为创建了一个新文件,这个文件记录的是路径。 

软链接一般就是相当于创建快捷方式,我们在Linux中是为了方便减少路径的输出和记忆使用的。

2.硬链接

使用创建软链接的命令不加上-s选项就是创建硬链接。我们来观察区别:

可以发现,我们向硬链接文件追加内容,源文件也有内容也同时修改,毕竟指向的是同一inode。当我们把硬链接文件删除,并不会影响源文件。

3.硬链接数

我们来讲解我们使用ll命令展示的目录文件中从来没有提及的一个参数:硬链接数

硬链接本质不是一个独立的文件。
这个链接数实际上是inode中的一个属性(count),被称为引用计数,记录当前有多少指针指向该inode。 

4.软硬链接的区别

硬链接不是独立的文件,没有独立indoe,硬链接本质是一组文件名和已经存在文件的映射关系。


软链接有独立的inode,内容上保存的是目标文件的路径!

我们也可以用硬链接对文件重命名和备份。

硬链接和复制不是同一回事!复制在磁盘上是开辟空间的,而硬链接只是改变inode的一个属性,并没有新开辟空间。

5.使用unlink删除链接的文件

我们可以使用unlink删除链接的文件,当然也可以删除普通的文件。

6.目录文件链接数( . 和 .. ) 

我们创建一个目录empty,之后观察链接数,之后进入empty,并在empty中创建目录dir,返回上级目录lesson20,在lesson20创建一个普通文件,观察empty的硬链接数的变化。

(注:dir默认创建后链接数是2) 

我们先分析dir目录为什么硬链接数是2: 

因为.代表当前文件。

而为什么我们在empty中创建一个新目录dir之后,empyt的硬链接数变为了3?是因为dir中的 .. 代表上级文件,其inode与其相同。

但是对于根目录,其中..和.对应的都是他自己:

Linux中,不允许对目录进行硬链接:

而对软链接,可以对目录操作,因为软链接里面存储的是路径。

二、静态库的制作和使用

回顾一下,我们之前说过,静态库相当于在宿舍装了台电脑;而动态库相当于是在去网吧玩电脑。各位直接看操作。

1.制作静态库

我们先手动制作一个静态库,不要想的很复杂,也就是写了一个.c文件和.h文件,但是没有写main方法。

我们将之前的文件缓冲区代码的my_stdio.c和my_stdio.h两个文件都拷贝进去,注意这里只是为了有几个头文件和.c文件,方便展示,文件中的内容与本博客中知识几乎无关,但是大家有兴趣可以看博主之前写的文件缓冲区的博客。

我们要将这些方法给别人用,制作静态库,.h头文件必须暴露,没必要藏。但是.c源文件需要隐藏,所以我们可以将.c编译为.o文件,之后把所有.o文件连接起来形成静态库。 

之后就是将这些.o文件打包形成静态库了,我们要使用一个新命令:

ar -rc xxx.a

当然刚才由于作者失误并没有打包.o文件,我们已经生成了库文件,此时需要往里面添加.o文件:

接下来我们来演示把头文件和库文件交给另一个人,看他如何使用。

2.使用静态库

2.1方法一

我们可以把库安装到系统中,把.h头文件也装到系统中,Linux系统中搜索头文件在/usr/include目录中,所以我们先把所有的头文件移动到该目录中(注意要提权)。

一般把库文件装在/lib64目录下:

所以Linux中的安装本质都是拷贝。 

我们创建一个other目录并进入,写一个main.c源文件,使用刚才的库和头文件。

之后我们编译这个.c文件:

目前属于编译时报错,因为/lib64中有很多库,我们不知道到底要找哪一个。

但是我们平时写的不包含自己写的库时,gcc/g++不需要指定库文件,是因为他们本身就是编译C/C++的,所以这些编译器一定本身就认识这些库的,不需要指定。但是我们的库相当于第三方库,我们要添加选项。

2.2方法二

当然还有其他方式,我们先把库和头文件都删除。

当时我们还没有删除可执行文件,我们进行完删除操作之后再执行a.out可执行文件:

发现还能执行。 因为程序在编译链接的时候把库的代码链接到可执⾏⽂件中,程序运⾏的时候将不再需要静态库

我们可以使用ldd(查看可执行文件或共享库(动态库)所依赖的动态库)命令。

这些静态库不一定要安装到系统中,可以就直接把库和头文件给你,你自己操作一番就可以使用。

我们在写程序的时候,自己写的头文件会使用双引号包起来,也就是在当前路径下找。

gcc在查库的时候,不会默认在当前路径下查找,是会去系统指定的路径下查找,所以我们要指定路径。

-L:告诉编译器,编译的时候,除了系统路径,也要在我指明的路径下查找。

2.3方法三

库发布的时候,把所有的头文件都放在include目录中;把库放在lib目录中。

为了方便创建,我们写一个makefile文件:

这里面的内容我们不做过多讲解,可以去看博主之前写的makefile文件的博客。

我们当然也可以把发布的文件压缩,方便去使用:

我们把发布的压缩包拷贝到要用的地方,并解压,此时直接编译肯定报错:

接下来要使用-I来指定除了系统路径找,还要到指定的路径下找头文件,当然还要指定目录,指定库名。

当然这里选项可以不带空格。

三、动态库的制作和使用

1.制作动态库

当我们要链接形成动态库的时候,需要使用gcc编译器,并且不能直接编译,需要带上-shared选项告诉编译器形成的是动态库

gcc -shared

当我们从.c文件形成.o时,因为要形成动态库,所以我们在形成.o文件时,也要加上一个选项 -fPIC 形成与位置无关码(嘿嘿,静态库加载其实和函数和变量的地址是有关的,在连接的时候会重定位,但这里是动态库,大家可以去看看《程序员的自我修养》这本书)。

fPIC:flag position ignore code

之后和静态库一样,将所有.o文件打包成动态库,但是记得加上-shared选项。

2.使用动态库

动态库又是如何让别人使用呢?还是三个方法。

2.1方法一

将头文件和动态库安装到(拷贝)系统路径下:

这里依旧需要指明用到的是哪个库:

这里也从侧面说明了动态库无论是编译期间还是链接期间都需要用到。

我们再次执行ldd命令看当前可执行程序依赖哪个库:

 我们把头文件删掉,把动态库也删掉。此时没有头文件是不会有影响的,因为头文件最多使用到编译阶段(步骤为:预编译、编译、汇编、链接),此时已经结果链接器生成了可执行文件,则头文件是否存在已经不重要,但是动态库没有则无法执行文件

2.2方法二

我们将拷贝的动态库和头文件都从系统目录中删除,依旧还是只有头文件和动态库,这次就和静态库的步骤相似,需要指定路径和库名了:

2.3方法三 

我们还是要把库发布,所以先更改makefile文件:

依旧是指定路径名找头文件,指定库路径名和指定库名:

此时你可能会发现,这和刚才的静态库好像没有区别,步骤都是一样的。

但是如果此时我们执行程序: 

它并没有运行。我们再次ldd看看它依赖哪些动态库:

但是我们已经告诉过编译器库在哪里了,为什么没有执行? 

动态库是要加载的!在程序运行的时候,和gcc没有关系了!

运行时是OS要加载你的程序,所以这个报错是OS说的。静态库OS不需要找

OS是在/lib64中找对应的库的,我们又是该如何给OS指定路径,查找自己的库?

  1. 拷贝到系统默认路径下,比如/lib64
  2. 我们可以建立一个软链接
  3. Linux中,OS查找动态库,是从环境变量中查找的。

环境变量?对,没错,就是这个:LD_LIBRARY_PATH

(这里因为作者配置过vim编译器,大家可以去下载一个vim编译器,当然还有其他方法链接到动态库)

我们使用export临时把动态库的路径导入LD_LIBRARY_PATH这个环境变量中。

但是我们知道,这只是内存级别的环境变量,我们可以将其写入到配置文件中(.bashrc)永久生效。

2.4方法四

如果我们想让系统找到库的路径,系统有全局的配置路径/etc/ld.so.conf.d/

这里面可以写各种配置文件。配置文件中, 我们可以在里面只写一个路径即可。

我们在里面创建一个112.conf配置文件,并写入动态库的绝对路径。

当我们把该路径设置到配置文件中,操作系统要重启,我们可以加载一下使用ldconfig命令:

这里其实一般建议使用方法一和方法三。

四、命令总结

1.关于软硬链接:

ln:创建软硬链接。

  • -s:创建软链接(不带该选项则是硬链接)。

unlink:删除链接文件,当然也可以删除非连接任意文件。

2.关于动静态库和连接命令:

ar:形成静态库。

  • -r:静态库中有该.o文件就替换它。
  • -c:静态库中没有该.o文件就创建它。

使用形式:

ar -rc xxx.a xxx.o xxx.o

ldd:查看当前可执行文件依赖哪些动态库。 

3.关于gcc编译器选项

-l:(这是小写的l)编译时指定库的名称选项。此时要把库的前缀lib和后缀.a/.so去掉。

-L:告诉编译器,编译的时候,除了系统路径,也要在我指明的路径下查找。查找的库文件

-I:(这是大写的i),告诉编译器,编译的时候,除了系统路径,也要在我指明的路径下查找头文件

-shared:将所有的.o打包形成.so动态库文件。

-fPIC:(flag position ignore code)将所有的.c形成与位置无关的.o文件。

总结:

这张内容其实很有用,但是我们并没有深入讲解,因为这里涉及很多关于编译原理和程序编译链接的知识,很多人都对这部分知识不以为然,但是真的很重要!有本书叫做《程序员的自我修养》,确实这部分知识其实从底层学习会让我们在日常生活中更好的知道一个程序崩溃时问题到底出现在哪,能更好的解决问题,这确实是一个程序员的自我修养!

至于ELF格式文件等之类的内容,作者会先暂停一段时间,因为作者还没有彻底搞懂那部分知识,写博客害怕误人子弟,不过等作者大彻大悟之时,一定会把这部分知识补上!敬请期待吧!

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

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

相关文章

数据结构(回顾)

数据结构(回顾) 回顾 不同点顺序表链表存储空间上物理上一定连续逻辑上连续,物理上不一定连续随机访问支持,时间复杂度O(1)不支持,时间复杂度O(N)任意位置插入或者删除元素可能需要挪动元素,效率低&#…

达梦数据库在Linux,信创云 安装,备份,还原

(一)系统环境检查 1操作系统:确认使用的是国产麒麟操作系统,检查系统版本是否兼容达梦数据库 V8。可以通过以下命令查看系统版本: cat /etc/os-release 2硬件资源:确保服务器具备足够的硬件资源&#xff0…

从0开始的操作系统手搓教程23:构建输入子系统——实现键盘驱动1——热身驱动

目录 所以,键盘是如何工作的 说一说我们的8042 输出缓冲区寄存器 状态寄存器 控制寄存器 动手! 注册中断 简单整个键盘驱动 Reference ScanCode Table 我们下一步就是准备进一步完善我们系统的交互性。基于这个,我们想到的第一个可以…

01-简单几步!在Windows上用llama.cpp运行DeepSeek-R1模型

1.llama.cpp介绍 Llama.cpp 是一个开源的、轻量级的项目,旨在实现 Meta 推出的开源大语言模型 Llama 的推理(inference)。Llama 是 Meta 在 2023 年开源的一个 70B 参数的高质量大语言模型,而 llama.cpp 是一个用 C 实现的轻量化…

HarmonyOS Next 属性动画和转场动画

HarmonyOS Next 属性动画和转场动画 在鸿蒙应用开发中,动画是提升用户体验的关键要素。通过巧妙运用动画,我们能让应用界面更加生动、交互更加流畅,从而吸引用户的注意力并增强其使用粘性。鸿蒙系统为开发者提供了丰富且强大的动画开发能力&…

JavaWeb-mysql8版本安装

下载方式 地址:https://www.mysql.com/cn/downloads/ 选择:MySQL Community (GPL) downloads 选择:MySQL Community Server 选择: 选择: 安装mysql (8.0.30) 1、以管理员身份 打开 命令行…

【实战ES】实战 Elasticsearch:快速上手与深度实践-3.2.3 案例:新闻搜索引擎的相关性优化

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 Elasticsearch新闻搜索引擎相关性优化实战3.2.3 案例:新闻搜索引擎的相关性优化项目背景1. 相关性问题诊断与分析1.1 初始查询DSL示例1.2 问题诊断矩阵1.3 性能基…

HCIA复习拓扑实验

一.拓扑图 二.需求 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到百度网络中HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分,PC1可以正常访问3.3.3.0/24网段,但是PC2不允许 3.学校内部路由使用静态路由,R1和R2之间两…

企业如何选择研发项目进度管理软件?盘点15款实用工具

这篇文章介绍了以下工具: 1. PingCode; 2. Worktile; 3. 腾讯 TAPD; 4. 华为 DevCloud; 5. 亿方云; 6. 阿里云效; 7. CODING 码云; 8. 明道云; 9. 进度猫; 10. 轻流等。 …

(二 十 二)趣学设计模式 之 备忘录模式!

目录 一、 啥是备忘录模式?二、 为什么要用备忘录模式?三、 备忘录模式的实现方式四、 备忘录模式的优缺点五、 备忘录模式的应用场景六、 总结 🌟我的其他文章也讲解的比较有趣😁,如果喜欢博主的讲解方式,…

conda 配置新环境时package will be install 和 package will be download 的区别

install 和 download 的区别 package will be downloaded下的包:这一类显示的是需要从 conda 仓库或其他指定的源下载的软件包。这些软件包通常是 .tar.bz2、.tar.xz 或 .conda 格式的压缩包。这些包会被下载到本地缓存目录(通常是 ~/.conda 或 C:\Users…

第本章:go 切片

注意: 切片必须要初始化 才能使用 ,切片是引用类型 a :[]int{} // 这上叫始化 此时并没有申请内存 // 如果要追加值的话: append ints : append(a, 1, 2, 3)a : make([]int,5) // 声明切片类型var a []string //声明一…

关于AI数据分析可行性的初步评估

一、结论:可在部分环节嵌入,无法直接处理大量数据 1.非本地部署的AI应用处理非机密文件没问题,内部文件要注意数据安全风险。 2.AI(指高规格大模型)十分适合探索性研究分析,对复杂报告无法全流程执行&…

编程考古-Borland历史:《.EXE Interview》对Anders Hejlsberg关于Delphi的采访内容(中)

为了纪念Delphi在2002年2月14日发布的25周年(2020.2.12),这里有一段由.EXE杂志编辑Will Watts于1995年对Delphi首席架构师Anders Hejlsberg进行的采访记录。在这次采访中,Anders讨论了Delphi的设计与发展,以及即将到来的针对Windows 95的32位版本。 Q. 编译器引擎本身是用…

Manus+Ollama实现本地大模型部署和应用测试

这几天Manus即DeepSeek后又突然火爆,我也进行了跟踪测试,特记录一下分享给大家,目前来看,Manus的确是一个可以进行任务分解的自动化解决方案,将其他AI需要多次繁杂的迭代对话做了较大的改进,相当于用户抛出…

【Python 数据结构 9.树】

我装作漠视一切,其实我在乎的太多,但我知道抓得越紧越容易失去 —— 25.3.6 一、树的基本概念 1.树的定义 树是n个结点的有限集合,n0时为空树。当n大于0的时候,满足如下两个条件: ① 有且仅有一个特定的结点&#xff…

LLM 学习(二 完结 Multi-Head Attention、Encoder、Decoder)

文章目录 LLM 学习(二 完结 Multi-Head Attention、Encoder、Decoder)Self-Attention (自注意力机制)结构多头注意力 EncoderAdd & Norm 层Feed Forward 层 EncoderDecoder的第一个Multi-Head AttentionMasked 操作Teacher Fo…

计算机网络软考

1.物理层 1.两个主机之间发送数据的过程 自上而下的封装数据,自下而上的解封装数据,实现数据的传输 2.数据、信号、码元 码元就是数字通信里用来表示信息的基本信号单元。比如在二进制中,用高电平代表 “1”、低电平代表 “0”&#xff0c…

VBA 数据库同一表的当前行与其他行的主键重复判断实现方案

目的,判断是否主键重复,不重复则登录新数据,重复则不登录。 定义类型: DataRecord   tableName 表名   rowNumber 行号   columnName 列名   data 数据 想要实现的代码逻辑如下: 模拟数据库的登录过程。假设…

2025最新群智能优化算法:山羊优化算法(Goat Optimization Algorithm, GOA)求解23个经典函数测试集,MATLAB

一、山羊优化算法 山羊优化算法(Goat Optimization Algorithm, GOA)是2025年提出的一种新型生物启发式元启发式算法,灵感来源于山羊在恶劣和资源有限环境中的适应性行为。该算法旨在通过模拟山羊的觅食策略、移动模式和躲避寄生虫的能力&…