前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Linux软硬链接与动静态库

Linux软硬链接与动静态库

作者头像
用户11317877
发布于 2025-02-19 01:43:10
发布于 2025-02-19 01:43:10
13800
代码可运行
举报
文章被收录于专栏:学习学习
运行总次数:0
代码可运行

1. 软硬链接

1.1 硬链接

我们看到, 真正找到磁盘上文件的并不是文件名, 而是inode, 其实在linux中可以让多个文件名对应于同一个inode.

  • abc和def的链接状态完全相同, 他们被称为指向文件的硬链接, 内核记录了这个连接数, inode789665的硬连接数为2.
  • 我们在删除文件时干了两件事情, 1. 在目录中将对应的记录删除 2. 将硬连接数-1, 如果为0, 则将对应的硬盘释放

1.2 软链接

硬链接是通过inode引用另外一个文件, 软链接是通过名字引用到另外一个文件, 但实际上, 新的文件和被引用的文件的inode不同, 应用场景上可以想象成一个快捷方式, 在shell中的做法:

1.3 软硬链接的对比

  1. 软链接是独立文件
  2. 硬链接只是文件名和目标文件inode的映射关系

1.4 软硬链接的用途

硬链接:

  1. . 和…就是硬链接
  2. 文件备份

软链接

  • 类似快捷方式

2. 什么是库

库是写好的现有的, 成熟的, 可以复用的代码. 现实中每个程序都要依赖很多基础的底层库, 不可能每个人的代码都是从零开始, 因此库的存在意义非同寻常.

本质上来说库是一种可执行代码的二进制形式, 可以被操作系统载入内存执行. 库有两种:

  • 静态库: .a[Linux], .lib[windows]
  • 动态库: .so[Linux], .dll[windows]

Centos 动静态库

C:

C++:

3. 制作动静态库

预备工作:

3.1 静态库

  • 静态库(.a) : 程序在编译链接的时候把库的代码链接到可执行文件中, 程序运行的时候将不再需要静态库.
  • 一个可执行程序可能用到许多的库, 这些库的运行有的是静态库, 有的是动态库, 而我们的编译默认为动态链接库, 只有在该库下找不到动态.so 的时候才会采用同名静态库, 我们也可以使用gcc 的 -static 强制设置链接动态库.
3.1.1 静态库的生成

注释: ar 是 gnu归档工具 rc表示(replace and create)

t: 列出静态库中的文件 v: verbose 详细信息

3.1.2 静态库的使用

在任意目录下, 新建 main.c 引入库头文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "my_stdio.h"
#include "my_string.h"
#include <stdio.h>
int main()
{
 	const char *s = "abcdefg";
 	printf("%s: %d\n", s, my_strlen(s));
 	mFILE *fp = mfopen("./log.txt", "a");
 	if(fp == NULL) return 1;
 	mfwrite(s, my_strlen(s), fp);
 	mfwrite(s, my_strlen(s), fp);
 	mfwrite(s, my_strlen(s), fp);
 	mfclose(fp);
 	return 0;
}
  • 场景一: 头文件和库文件都已经安装到系统路径下

头文件安装到系统路径下, 图下:

库文件安装到系统路径下, 图下:

此时进行gcc main.c 进行编译会出现链接错误, 这是因为系统路径下gcc默认只会链接C的库, 第三方库需要进行指明

使用如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc main.c -lmystdio
//-l 表示指定链接的库, 空格可带可不带
  • 场景二: 头文件和库文件和我们自己的源文件在同一个路径下

头文件的查找规则是先查找同级目录, 在查找系统目录, 很显然头文件这里不会报错, 但是库找不到, 库只会在系统路径下查找, 这时候需要指明系统路径, 指明路径之后并且指明链接的库

使用如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc main.c -L. -lmymath
//-L表示指明库的路径
  • 场景三: 头文件和库文件都不在当前路径下, 都有自己独立的路径

找不到头文件 , 头文件和main.c不在同一级目录下, 也不在系统目录下

此时头文件找到了, 现在库找不到了

有库的路径但不知道链接哪个库

此时编译成功.

使用如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc main.c -I头⽂件路径 -L库⽂件路径 -lmymath
// -I指明头文件路径

总结:

  • 测试目标文件生成后, 静态库删掉, 程序照样可以运行
  • 库文件名称和引入库文件名称: 去掉前缀lib, 去掉后缀 .so , .a : 如: libc.so -> c

3.2 动态库

  • 动态库(.so) : 程序在运行的时候才去链接动态库的代码, 多个程序共享使用库的代码
  • 一个与动态库链接的可执行文件仅仅包含他用到的函数入口地址的一个表, 而不是外部函数所在目标文件的整个机器码
  • 在可执行文件开始运行以前, 外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中, 这个过程称为动态链接(dynamic linking)
  • 动态库可以在多个程序间共享, 所以动态链接使得可执行文件更小, 节省了磁盘空间. 操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程公用, 节省了内存和磁盘空间.
3.2.1 动态库的生成
  • shared: 表示生成共享库格式
  • fPIC: 产生位置无关码(position independent code)
  • 库名规则: libxxx.so
3.2.2 动态库的使用
  • 场景一: 头文件和库文件安装到系统路径下

此时我们直接编译会造成链接错误, 和静态库一样

使用如下代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc main.c -lmystdio

场景二: 头文件和库文件和我们自己的源文件在同一个路径下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc main.c -L. -lmymath // 从左到右搜索-L指定的⽬录

场景三: 头文件和库文件都有自己的独立路径

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$ gcc main.c -I头⽂件路径 -L库⽂件路径 -lmymath

ldd查看可执行文件依赖哪些库

问题1:

如果我把库中的文件都删掉了, 就会报如下错误

因为是动态链接的, 删掉了就会造成链接错误, 而静态链接不会

解决方案:

  • 拷贝.so 文件到系统共享路径下, 一般指/usr/lib, /usr/local/lib, /lib64或者开篇指明的库路径等
  • 向系统共享路径下建立同名软连接
  • linux系统中, OS会查找动态库和环境变量, 更改环境变量 : LD_LIBRARY_PATH

但是重启xshell之后自己导入的环境变量就没了, 此时可以添加到 .bashrc中

  • ldconfig方案: 配置/etc/ld.so.conf.d/, ldconfig更新

把库的路径写入配置文件中, 系统会在配置文件中的路径寻找库, 自己创建一个配置文件, 如下

然后 命令行输入ldconfig, 此时即可

程序运行时和gcc没关系了, gcc是告诉编译器, 接下来OS要加载你的程序

如何给系统指定路径, 查找我自己的动态库, 如上就是解决方案

问题2:

如果同时提供.so .a gcc/g++默认使用什么库呢?

动态库

如果想要静态链接, 需要添加-static

注意

如果你要强制静态链接, 必须提供对应的静态库

如果你只提供静态库, 但是连接方式是动态链接, gcc, g++没得选, 只能针对你的.a局部采用静态链接, 所以把系统路径下的库删除, 运行也能跑


完, 您的点赞收藏是我更新的最大动力!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-02-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
上次介绍了基础IO(二):Linux:基础IO(二.缓冲区、模拟一下缓冲区、详细讲解文件系统)
是Nero哦
2024/07/01
3020
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
【Linux】基础I/O>文件系统&&软硬链接&&动静态库详解
操作文件,除了上述C接口(当然,C++也有接口,其他语言也有),我们还可以采用系统接口来进行文件访问,先来直接以代码的形式,实现和上面一模一样的代码
用户10925563
2024/06/04
1590
【Linux】基础I/O>文件系统&&软硬链接&&动静态库详解
【Linux修炼】14.磁盘结构/文件系统/软硬链接/动静态库
在之前文件的学习中,一开始我们就提到了文件操作的本质是进程和被打开文件之间的关系,那没有没打开的文件呢?如果一个文件没有被打开,该如何被OS管理呢?
每天都要进步呀
2023/03/28
1.1K0
【Linux修炼】14.磁盘结构/文件系统/软硬链接/动静态库
解锁动静态库的神秘力量1:从代码片段到高效程序的蜕变
本篇博主将带大家基于linux系统方面了解动静态库是什么,怎么创建以及如何使用等一些注意事项,希望能对大家在这方面的学习有所帮助。
羑悻的小杀马特.
2025/01/23
660
解锁动静态库的神秘力量1:从代码片段到高效程序的蜕变
【Linux】基础IO(文件系统)
一般而言,OS未来和磁盘交互的时候,基本单位为;4KB,而不是512字节(一个扇区512字节),因为一次读512字节太少了,要提高效率。
秦jh
2024/10/15
1370
【Linux】基础IO(文件系统)
【Linux】软硬链接和动静态库
所以我们说Linux下一切皆文件,那么目录是文件吗?是的,因为它也有自己的inode,我们可以通过ls -i的命令来查看我们目录对应的inode
s-little-monster
2025/02/21
1230
【Linux】软硬链接和动静态库
【Linux】软硬链接和动静态库
  在Linux系统中,文件链接分为两种类型:硬链接(Hard Link)和软链接(也称为符号链接或Symbolic Link)。它们都是用于创建文件的额外入口点,但是工作原理和使用场景有所不同。
大耳朵土土垚
2024/11/10
2170
【Linux】软硬链接和动静态库
【Linux】探索文件I/O奥秘,解锁软硬链接与生成动静态库知识
仔细观察发现,这三个流的类型都是FILE*, fopen返回值类型,文件指针,那什么是FILE类型呢?这是C标准库自己封装的一个结构体。
用户11316056
2024/10/16
1190
【Linux】探索文件I/O奥秘,解锁软硬链接与生成动静态库知识
【Linux】软硬连接与动静态库
硬连接不是一个独立的文件,因为它没有的独立的inode号,用的是目标文件的inode
用户11029103
2025/03/10
1060
【Linux】软硬连接与动静态库
深入浅出动静态库
  当你在Linux系统上编写和运行程序时,动态库和静态库是两个非常重要的概念。它们不仅影响着程序的编译和执行效率,还直接关系到程序的可移植性和灵活性
用户11029129
2024/06/04
1560
深入浅出动静态库
【Linux】从零开始认识动静态库 - 静态库
今天我们来学习动静态库。我们之前有没有使用过库呢??? 当然了: strerror strstr strcpy memset...等函数都要有具体的实现,那这个具体的实现在哪里呢???就是在我们的库中!
叫我龙翔
2024/05/11
2310
【Linux】从零开始认识动静态库 - 静态库
动态库与静态库
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库。
二肥是只大懒蓝猫
2023/03/30
2.4K0
动态库与静态库
【Linux】软硬链接与动静态库
 我们发现,每一个不同文件的inode编号都不相同,所以inode可以说是用来标识文件的标识符。接下来,我们通过下面指令来给mysoft文件,创建软链接:
诺诺的包包
2023/10/15
2770
【Linux】软硬链接与动静态库
【Linux】动静态库
静态库是一种在编译阶段将库文件的内容直接整合到目标程序中的库文件形式。使用静态库后,库的代码会成为可执行文件的一部分,运行时不需要依赖外部库。
用户11305458
2025/01/09
1530
【Linux】动静态库
【Linux】动静态库(超详细)
💢 由于CentOS 8系统2021年12月31日已停止维护服务,CentOS 7系统将于2024年06月30日停止维护服务。CentOS官方不再提供CentOS 9及后续版本,不再支持新的软件和补丁更新。CentOS用户现有业务随时面临宕机和安全风险,并无法确保及时恢复。
IsLand1314
2024/11/19
1190
【Linux】动静态库(超详细)
【Linux篇】革新编程方式:如何开发让人眼前一亮的库
库(Library)是指一组已封装、可复用的代码集合,通常以函数、类或模块的形式提供。它将常见或复杂的功能抽象出来,供开发者直接调用,而无需重复实现。根据链接方式,可分为静态库(在编译时合并到可执行文件)和动态库(在运行时加载);根据用途,又可细分为通用工具库、领域专用库等。通过引入库,项目能够保持结构清晰、降低耦合、加快开发速度,同时也便于维护和升级。
熬夜学编程的小王
2025/04/15
740
动静态库:选择与应用的全方位指南
那么这样inode中一定有一个引用计数的变量用于记录这个inode编号有多少段映射关系。
绝活蛋炒饭
2024/12/16
950
动静态库:选择与应用的全方位指南
【Linux系统IO】六、动静态库
​ 我们之前学 gcc 的时候也有接触过一点动静态库的知识,现在要把它单独拿出来讲,主要是因为我们后面肯定在自己开发的时候需要包装自己的库,此时就需要有动静态库的原理知识和使用知识!
利刃大大
2025/03/11
1060
【Linux系统IO】六、动静态库
Linux gcc编译生成静态库和共享动态库的过程
这篇文章主要通过实例演示在Linux下如何使用gcc分别编译生成静态库和动态库文件以及其它程序如何使用这个生成的静态库和动态库。
typecodes
2024/03/29
8480
Linux gcc编译生成静态库和共享动态库的过程
C语言 | 什么是静态链接库和动态链接库?
今天分享的是静态链接库和动态链接库的相关知识,并且自己动手写一个简单的静态函数库和动态函数库,来体验这个流程。
飞哥
2020/08/11
4.8K0
C语言 | 什么是静态链接库和动态链接库?
相关推荐
Linux:基础IO(三.软硬链接、动态库和静态库、动精态库的制作和加载)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验