【Linux】软硬链接和动静态库


文章目录
- 1. 软硬链接
- 💥硬链接(Hard Link)
- 💥软链接(Symbolic Link)
- 2. 动静态库
- 💥静态库(Static Libraries)
- 💥动态库(Dynamic Libraries)
1. 软硬链接
在Linux系统中,文件链接分为两种类型:硬链接(Hard Link)和软链接(也称为符号链接或Symbolic Link)。它们都是用于创建文件的额外入口点,但是工作原理和使用场景有所不同。
💥硬链接(Hard Link)
- 定义:硬链接是一个指向原始文件的直接链接。硬链接是一个与原始文件共享inode的文件,它们在文件系统中实际上是同一个文件。
每个文件在Linux系统中都有一个inode,它包含了文件的所有元数据信息,如权限、所有者等,但不包含文件名。当创建一个硬链接时,实际上是为同一个inode创建了一个新的文件名,这意味着两个或多个硬链接实际上指向的是同一个文件数据。
- 特性:
- 硬链接不能跨文件系统。
- 不能对目录创建硬链接(除了
ln
命令的特殊选项外,这通常是为了安全考虑)。 - 对一个文件的修改会反映在所有的硬链接上
- 如果原始文件被删除,只要还有一个硬链接存在,文件的数据就不会被删除。
删除原始文件后,硬链接仍然可以访问原始文件的内容,这是因为Linux系统在创建硬链接时,会使用引用计数的方式,记录一个文件共有多少个硬链接,当删除一个文件时,只有将其所有的硬链接都删除,这个文件才算真正的删除,否则都可以通过任意一个硬链接访问文件内容。
- 创建方法:使用
ln
命令。例如,要为文件file.txt
创建一个名为file-hard.link
的硬链接,可以执行命令ln file.txt file-hard.link
。(注意文件的后缀可以随意选择)
最开始创建file.txt文件,只有它自己,所以引用计数为1,后来为它新建了一个硬链接file-hard.link,引用计数就变为2,因为它们两个本质上是同一个文件,所以file-hard.link的引用计数也为2,与file.txt保持一致。
关于引用计数:
新建一个目录文件,它一开始的硬链接引用计数就是2,除了它自己以外,它里面还包含一个隐藏文件.
,这个其实也是该目录的硬链接,如下图所示:
而上图中的
..
文件则是指向上一级目录的硬链接,每个目录在创建的时候都会自动创建这两个文件。
💥软链接(Symbolic Link)
- 定义:软链接是一个指向原始文件或目录的特殊文件,它包含了另一个文件或目录的路径名。通过访问软链接,可以间接访问源文件。
这意味着软链接形成的文件是不同于原始文件的,它们有着不同的inode编号,与硬链接不同
-
特性:
- 软链接可以跨文件系统。
- 可以对文件或目录创建软链接。
- 如果原始文件或目录被移动或删除,软链接将失效(变为“断开”状态)。
- 原始文件的权限信息、时间戳等软链接都是不保留的,它仅仅保存了原始文件的路径名。
-
创建方法:使用
ln -s
命令。例如,要为文件sfile.txt
创建一个名为sfile-soft.link
的软链接,可以执行命令ln -s sfile.txt sfile-soft.link
。
使用场景:
- 硬链接适合于需要确保文件不会因为原文件的删除而丢失的情况,尤其是在同一文件系统内。减少磁盘空间占用以及创建备份文件等场景。
- 软链接则更灵活,适用于需要跨文件系统链接或者链接到可能经常变动的位置的情况。此外,软链接可以更容易地识别和管理,因为它们本质上是文本形式的路径。
总结起来,软连接有独立的inode,软连接内容上保存的是目标文件的路径,当原始文件删除后,软链接将会失效;例如windows的快捷方式。而硬链接不是独立的文件,没有独立的inode,本质是一组文件名与目标文件的映射关系(别名),删除原始文件后,因为引用计数的存在,本质目标文件并没被删除,硬链接仍然可以访问原始文件的内容。
2. 动静态库
在Linux系统中,库文件分为静态库(Static Libraries)和动态库(Dynamic Libraries)。这两种类型的库各有优缺点,适用于不同的场景。
💥静态库(Static Libraries)
定义:
- 静态库是在编译阶段就被链接到目标代码中的库。这意味着当一个程序被编译时,它会包含它所依赖的静态库的副本。
优点:
- 程序运行时不需要外部库文件,因为所有需要的代码都已经被整合进可执行文件中。
- 可以确保程序总是使用特定版本的库,避免了所谓的“DLL地狱”问题(在Windows环境中常见,指的是由于不同应用程序可能依赖于不同版本的同一个库而导致的问题)。
缺点:
- 每个使用该库的程序都会有一个库的副本,这会导致磁盘空间的浪费。
- 如果静态库需要更新,那么所有使用这个库的应用程序都需要重新编译和链接。
创建静态库
- 编写源代码并将其编译为目标文件(.o):
gcc -c mystdio.c -o mystdio.o
- 创建静态库文件可以使用
ar
命令:ar rc libmystdio.a mystdio.o
libmystdio.a
是静态库文件的名称mystdio.o
是要打包进库文件的目标文件rc
表示replace create
静态库通常具有
.a
扩展名。
使用静态库
方法一:使用带路径的库进行链接
gcc myprogram.c -I/path/to/include -L/path/to/library -lmylib -o myprogram
-
-I/path/to/include
指定头文件所在的路径 -
-L/path/to/library
指定库文件所在的路径 -
-lmylib
指定要链接的库文件的名称(省略了前缀lib
和文件扩展名.a
) -
使用静态库进行链接时,可以使用
-l
和-L
选项指定库文件的位置和名称,-l
指定库的名字
gcc在查动静态库时不会在当前目录下查,所以我们需要指定路径
方法二:将库安装到系统中直接使用
- 首先,编译源代码生成静态库文件(通常以
.a
为文件扩展名)。可以使用gcc
或g++
命令进行编译。例如,编译一个名为libexample.a
的静态库文件可以使用以下命令:
gcc -c example.c # 编译源代码生成目标文件
ar rc libexample.a example.o # 使用ar工具将目标文件打包成静态库
- 将生成的静态库文件复制到系统目录中,例如
/lib64/
。可以使用cp
命令进行复制,例如:
sudo cp libexample.a /lib64/ # 将静态库文件复制到系统目录
sudo cp libexample.h /usr/include/ #将静态库头文件复制到系统目录
- 更新库缓存。在某些Linux发行版中,需要手动更新库缓存以使系统可以找到新安装的库。可以使用以下命令更新库缓存:
sudo ldconfig # 更新库缓存
- 确认安装成功。可以使用
ls
命令检查静态库文件是否已经复制到系统目录中,例如:
ls /lib64/libexample.a # 检查静态库文件
- 在编译和链接其他程序时,可以使用
-l
选项指定使用安装的静态库。例如,使用gcc
命令编译一个名为example_program.c
的程序,并链接使用静态库libexample.a
可以使用以下命令:
gcc example_program.c -o example_program -lexample
链接库时需要省去前缀lib和后缀.a,动态库也是一样,直接 -lexample即可
这样,就可以将静态库安装到系统中,并且可以直接在其他程序中使用该库。
💥动态库(Dynamic Libraries)
定义:
- 动态库(也称为共享库)是在程序运行时被加载的。这意味着多个程序可以共享同一份库文件,从而节省内存和磁盘空间。
优点:
- 节省磁盘空间和内存,因为多个程序可以共享同一个库文件。
- 库更新时不需要重新编译或重新链接应用程序,只需替换库文件即可(前提是API没有改变)。
缺点:
- 程序运行时需要有相应的动态库存在,否则可能会导致程序无法启动。
创建动态库
- 动态库通常具有
.so
(shared object) 扩展名。 - 创建动态库可以使用
gcc
编译器的-fPIC
和-shared
选项。
例如,编译一个名为libexample.so
的动态库文件可以使用以下命令:
gcc -fPIC -c example.c #编译.o文件
gcc -shared -o libexample.so example.o # 编译源代码生成动态库
-fPIC:形成与位置无关码
使用动态库
方法一:使用带路径的库进行链接
这里与静态库一致
gcc myprogram.c -I/path/to/include -L/path/to/library -lmylib -o myprogram
-
-I/path/to/include
指定头文件所在的路径 -
-L/path/to/library
指定库文件所在的路径 -
-lmylib
指定要链接的库文件的名称(省略了前缀lib
和文件扩展名.a
) -
使用动态库进行链接时,可以使用
-l
和-L
选项指定库文件的位置和名称,-l
指定库的名字 -
可以使用
ldd
命令查看一个程序所依赖的动态库列表,例如:ldd myprogram
。
gcc在查动静态库时不会在当前目录下查,所以我们需要指定路径
注意链接动态库形成可执行程序后,运行可执行文件时,系统是需要找到动态库的位置,也就是运行可执行程序时,动态库是需要加载的,所以如何让系统找到动态库?
- 将动态库文件复制到系统目录中,系统会默认在该目录下寻找
- 在系统路径建立动态库文件的软链接
- Linux系统中除了会在系统路径下寻找动态库,还会在环境变量中寻找,该环境变量为
LD_LIBRARY_PATH
- ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
方法二:将库安装到系统中直接使用
- 将生成的动态库文件复制到系统目录中,例如
/lib64
。可以使用cp
命令进行复制,例如:
sudo cp libexample.so /lib64/ # 将动态库文件复制到系统目录
sudo cp libexample.h /usr/include/ #将静态库头文件复制到系统目录
- 更新库缓存。在某些Linux发行版中,需要手动更新库缓存以使系统可以找到新安装的库。可以使用以下命令更新库缓存:
sudo ldconfig # 更新库缓存
- 确认安装成功。可以使用
ls
命令检查动态库文件是否已经复制到系统目录中,例如:
ls /lib64/libexample.so # 检查动态库文件
- 在编译和运行其他程序时,可以使用
-l
选项指定使用安装的动态库。例如,使用gcc
命令编译一个名为example_program.c
的程序,并链接使用动态库libexample.so
可以使用以下命令:
gcc example_program.c -o example_program -lexample
这样,就可以将动态库安装到系统中,并且可以直接在其他程序中使用该库。此外,编译形成可执行程序后,如果删除了需要的动态库,程序也是不可以运行的。
原理上理解动态库:
进程在链接动态库时,操作系统会先将动态库加载到内存中,然后将动态库在内存中的地址通过页表映射到进程地址空间的共享区,这样进程在执行库方法的时候就是在自己的地址空间中跳转运行的。当另一个程序也要使用同一个动态库时就不需要再重复加载该动态库到内存里了,只需要通过进程的页表进行映射之前加载到内存的动态库即可,多个程序也是这样。
总结
如果同时提供动态库与静态库,gcc/g++默认使用动态库;如果要使用静态库必须使用静态链接-static
来指明;如果使用动态链接但是只有静态库,那么gcc/g++只能选择静态库进行链接。
选择使用静态库还是动态库取决于具体的需求。如果关注程序的独立性和稳定性,且不介意较大的程序大小,可以选择静态库;如果更关心资源的有效利用,并且可以保证目标系统上有适当的动态库版本,那么使用动态库是更好的选择。
相关文章:

【Linux】软硬链接和动静态库
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…...

HarmonyOS入门 : 获取网络数据,并渲染到界面上
1. 环境搭建 开发HarmonyOS需要安装DevEco Studio,下载地址 : https://developer.huawei.com/consumer/cn/deveco-studio/ 2. 如何入门 入门HarmonyOS我们可以从一个实际的小例子入手,比如获取网络数据,并将其渲染到界面上。 本文就是基于…...
【贪心】【哈希】个人练习-Leetcode-1296. Divide Array in Sets of K Consecutive Numbers
题目链接:https://leetcode.cn/problems/divide-array-in-sets-of-k-consecutive-numbers/description/ 题目大意:给出一个数组nums[]和一个数k,求nums[]能否被分成若干个k个元素的连续的子列。 思路:比较简单,贪心就…...

【数据库实验一】数据库及数据库中表的建立实验
目录 实验1 学习RDBMS的使用和创建数据库 一、 实验目的 二、实验内容 三、实验环境 四、实验前准备 五、实验步骤 六、实验结果 七、评价分析及心得体会 实验2 定义表和数据库完整性 一、 实验目的 二、实验内容 三、实验环境 四、实验前准备 五、实验步骤 六…...

Web服务nginx基本实验
安装软件: 启动服务: 查看Nginx服务器的网络连接信息,监听的端口: 查看默认目录: 用Windows访问服务端192.168.234.111的nginx服务:(防火墙没有放行nginx服务,访问不了) …...

Ubuntu实现双击图标运行自己的应用软件
我们知道在Ubuntu上编写程序,最后编译得到的是一个可执行文件,大致如下 然后要运行的时候在终端里输入./hello即可 但是这样的话感觉很丑很不方便,下边描述一种可以类似Windows上那种双击运行的实现方式。 我们知道Ubuntu是有一些自带的程序…...
js id字符串转数组
将一个逗号分隔的字符串(例如 "12,123,213,")转换为一个 JavaScript 数组,并去除多余的逗号,可以使用以下几种方法。这里我将展示几种常见的方式: 方法 1: 使用 split 和 filter 你可以使用 split 方法将字…...

《手写Spring渐进式源码实践》实践笔记(第十八章 JDBC功能整合)
文章目录 第十八章 JDBC功能整合背景技术背景JDBC JdbcTemplate关键特性 用法示例业务背景 目标设计实现代码结构类图实现步骤 测试事先准备属性配置文件测试用例测试结果: 总结 第十八章 JDBC功能整合 背景 技术背景 JDBC JDBC(Java Database Conne…...

边缘计算在智能交通系统中的应用
💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 边缘计算在智能交通系统中的应用 引言 边缘计算概述 定义与原…...
HTML5+css3(浮动,浮动的相关属性,float,解决浮动的塌陷问题,clear,overflow,给父亲盒子加高度,伪元素)
浮动的相关属性 以下使浮动的常用属性值: float: 设置浮动 以下属性: left : 设置左浮动 right : 设置右浮动 none :不浮动,默认值clear 清除浮动 清除前面兄弟元素浮动元素的响应 以下属性: left &…...

【C++ 滑动窗口】2134. 最少交换次数来组合所有的 1 II
本文涉及的基础知识点 C算法:滑动窗口及双指针总结 LeetCode2134. 最少交换次数来组合所有的 1 II 交换 定义为选中一个数组中的两个 互不相同 的位置并交换二者的值。 环形 数组是一个数组,可以认为 第一个 元素和 最后一个 元素 相邻 。 给你一个 二…...
使用 PyTorch 实现并测试 AlexNet 模型,并使用 TensorRT 进行推理加速
本篇文章详细介绍了如何使用 PyTorch 实现经典卷积神经网络 AlexNet,并利用 Fashion-MNIST 数据集进行训练与测试。在训练完成后,通过 TensorRT 进行推理加速,以提升模型的推理效率。 本文全部代码链接:全部代码下载 环境配置 为了保证代码在 GPU 环境下顺利运行,我们将…...
Python 数据可视化详解教程
Python 数据可视化详解教程 数据可视化是数据分析中不可或缺的一部分,它通过图形化的方式展示数据,帮助我们更直观地理解和分析数据。Python 作为一种强大的编程语言,拥有丰富的数据可视化库,如 Matplotlib、Seaborn、Plotly 和 …...
springboot集成opencv开源计算机视觉库
最近项目需要用到opencv,网上看到很多资料都是下载安装并且引入jar包与dll文件,感觉很麻烦,不是我想要的,于是花时间折腾了下,不需要任何安装与引入jar包与dll文件,简单方便,快速上手。 先说说…...

CCF ChinaOSC |「开源科学计算与系统建模openSCS专题分论坛」11月9日与您相约深圳
2024年11月9日至10日,以“湾区聚力 开源启智”为主题的2024年中国计算机学会中国开源大会(CCF ChinaOSC)将在深圳召开。大会将汇聚国内外学术界、顶尖科技企业、科研机构及开源社区的精英力量,共同探索人工智能技术和人类智慧的无…...

2024年11月8日上海帆软用户大会
2024年11月8日上海帆软用户大会 2024年11月8日,上海成功举办了帆软用户大会,主题为“数字聚力,绽放新机”。大会汇聚了众多行业专家和企业代表,共同探讨数字化转型和商业智能领域的最新趋势和实践。 大会亮点: 专家…...
信息泄露漏洞一文速通
文章目录 信息泄露漏洞一文速通敏感信息の概念敏感信息の分类企业敏感信息用户敏感信息站点敏感信息 如何挖掘信息泄露漏洞?信息泄露风险清单(checklist)未授权访问类文件与数据泄露开发与调试信息泄露公共配置文件泄露其他敏感信息泄露点 威…...
Android 启动时应用的安装解析过程《二》
上一篇内容说到InitAppsHelper这个类的initSystemApps函数,只说了一下几个重要参数的来源还没展开,这里继续,有兴趣的可以看链接: Android 启动时应用的安装解析过程《一》 一、系统应用的扫描安装 /*** Install apps from system dirs.*/Gu…...
智谱AI:ChatGLM强大的生成式语言模型
目录 智谱AI:ChatGLM强大的生成式语言模型 一、ChatGLM的定义与特点 二、ChatGLM的应用场景 三、举例说明 四、注意事项 智谱AI:ChatGLM强大的生成式语言模型 它通过对话的方式能够生成自然流畅的文本,这一特性使其在多个领域都有广泛的应用潜力,特别是在智能对话和智能…...
git tag
已经发布了 v1.0 v2.0 v3.0 三个版本,这个时候,我突然想不改现有代码的前提下,在 v2.0 的基础上加个新功能,作为 v4.0 发布。就可以检出 v2.0 的代码作为一个 branch ,然后作为开发分支。 要查看仓库中的所有标签 gi…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Fabric V2.5 通用溯源系统——增加图片上传与下载功能
fabric-trace项目在发布一年后,部署量已突破1000次,为支持更多场景,现新增支持图片信息上链,本文对图片上传、下载功能代码进行梳理,包含智能合约、后端、前端部分。 一、智能合约修改 为了增加图片信息上链溯源,需要对底层数据结构进行修改,在此对智能合约中的农产品数…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换
目录 关键点 技术实现1 技术实现2 摘要: 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式(自动驾驶、人工驾驶、远程驾驶、主动安全),并通过实时消息推送更新车…...

DBLP数据库是什么?
DBLP(Digital Bibliography & Library Project)Computer Science Bibliography是全球著名的计算机科学出版物的开放书目数据库。DBLP所收录的期刊和会议论文质量较高,数据库文献更新速度很快,很好地反映了国际计算机科学学术研…...

DeepSeek源码深度解析 × 华为仓颉语言编程精粹——从MoE架构到全场景开发生态
前言 在人工智能技术飞速发展的今天,深度学习与大模型技术已成为推动行业变革的核心驱动力,而高效、灵活的开发工具与编程语言则为技术创新提供了重要支撑。本书以两大前沿技术领域为核心,系统性地呈现了两部深度技术著作的精华:…...