Linux:软硬链接及动静态库

news/2024/11/15 6:15:03/

一、Linux中的链接文件

1.1硬链接及应用场景

ln//创建硬链接

 我们再创建一个硬链接生成的文件。

我们可以看到mlink.hard的inode和makefile.c的inode都是一样的,inode一样里面的数据自然也是一样。相当于对make.file进行了一个重命名,所以硬链接一定没有新建文件,因为其没有新建inode,所以硬链接新建的是文件名和源文件的inode建立了个映射关系。

也就变成了有两个文件名和一个inode建立了映射关系。

而权限之后的数字就是硬链接数,硬链接本质上就是在指定目录下,插入新的文件名和目标文件的映射关系,并让inode的引用计数,每次创建一个硬链接就++。

可我们可以发现,我们新建的文件默认硬链接数是1,这个1就是路径下的.

 而当我们新创建一个文件夹4.5时会发现硬链接数为2。因为除了自身文件名和inode对应,在此当前目录下包含.文件作为硬链接,链接到自己。


 

此外可以看到,创建了4.5这个目录后,2024.4目录的硬链接数就变为了3,这是因为首先是2024.4指向inode,然后是目录下的.然后还有刚刚创建的4. 5中的.. 

这就是我们cd..可以回到上级目录的原因,因为..作为上级目录的硬链接指向其,inode,我们还可以看到2024.4目录下的..硬链接数为9,~目录的硬链接数为9。

所以一个目录下有多少个子目录,可以通过硬链接数-2得到

注意,Linux中不允许用户给目录建立硬链接,比如在一个目录下建立一个dir硬链接链接到根目录,那我们在寻找查询一个文件的时候查询到dir就会回到根目录形成环路问题,也就是无穷的循环递归现象。除非系统自己建立,只要建立硬链接不管是.还是..都会形成环路问题,而.和..已经被系统做了特殊标识,操作系统会对.和..做特殊处理,而如果让用户自己建立操作系统就无法辨别。

1.2软链接及应用场景

ln -s//建立软链接

mlink.soft本质上是一个文件。

ll -li我们可以看到mlink.soft有自己的inode。

软链接本质就是一个独立的文件,软链接里面放的是目标文件的路径,就类似于windows中的桌面快捷方式。

 软链接可以指向比较深的文件路径,直接./直接就可以运行或操作目标文件。

 可以看到有很多软链接 。

二、动静态库

 2.1什么是动静态库

ldd XXX//查看文件链接哪一个动态库

库被分为两种,动态库(后缀为.so),静态库(后缀为.a)

一般云服务器,都是默认安装动态库,生成可执行程序时也是默认链接动态库。

我们每次生成的可执行程序,都用到了Linux中的C/C++的动态库。 

我们可以通过gcc 文件名 -static 的方式来链接静态库,静态链接的可执行程序的大小是比动态链接的可执行程序是要大很多的。

 一般判断一个库的名字都是去掉前缀lib,去掉后缀so.剩下的就是它的名字,比如libc.so.6去掉前后缀就是c,所以这就是我们的c语言的库。

2.2静态库的制作和使用

所以为什么要有库呢?

1.基于已经实现的库可以提高开发效率

2.隐藏源代码

[root@localhost linux]# ls
add.c add.h main.c sub.c sub.h
[root@localhost linux]# gcc -c add.c -o add.o
[root@localhost linux]# gcc -c sub.c -o sub.o
生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o 
ar是gnu归档工具,rc表示(replace and create)
查看静态库中的目录列表
[root@localhost linux]# ar -tv libmymath.a 
rw-r--r-- 0/0 1240 Sep 15 16:53 2017 add.o
rw-r--r-- 0/0 1240 Sep 15 16:53 2017 sub.o
t:列出静态库中的文件
v:verbose 详细信息
[root@localhost linux]# gcc main.c -L. -lmymath
-L 指定库路径
-l 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行

所以库的本质就是把一堆.o打包形成一个文件,然后通过头文件来调用库。注意,库中不能包含main函数。

这里将mymath.o和mystdio.o打包形成名为libmyc.a的静态库,我们可以直接将头文件和.o文件传输给其他人,别人就可以在main函数中进行包含使用,当然如果直接用gcc编译的话会报错,因为gcc默认使用libc.so.6的库,编译器默认去lib64路径下去找库,此时肯定是找不到的。

需要gcc源文件,然后链接自己构造的库,-l链接文件名,-L .表明库文件在当前路径下。然后可以编译成功。

2.3动态库的制作和使用

gcc -c -FPIC文件名//形成同名的.o
gcc -o -shared libXXX.so XXX.o XXX.o//形成名为XXX的动态库

shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
也可以通过makefile文件来进行生成目标文件
补充:$<是将依赖文件依次执行指令。也可以向下面这样写:将所有.c结尾的编译成同名.o 

所以一个编写库的人未来交给别人的

我们也可以通过output将文件创建打包到一个目录下,不同类型的文件打包到不同的子目录下。

之后就可以直接将压缩包mylib.tgz上传转移等操作 ,之后拿到压缩包的人直接进行解压操作就可以拿到文件。

而在直接编译刚刚自己写的第三方库时编译器会进行报错,无法查找到mymath.c。因为编译器在编译时1.默认会到include所在路径下去找2.在当前路径下找,而头文件我们刚刚将其封装在了lib目录下,所以无法查找。

-I就是告诉编译器目标头文件在哪个路径下。

可是这种编译方式及其的繁琐复杂,这时可以采用更好的方式,将include目录和lib目录分别拷贝到include和lib64这样的系统指定的路径中,所以所谓的把库、软件安装到系统中,本质就是将对应的文件,拷贝到系统指定的路径中(一般都是系统)

像类似与stdio.h等都在include路径下。

所以像节省编写时的繁杂操作,我们可以直接将相关文件拷贝到系统指定的路径下。

但编译形成可执行程序后,./去运行发现依然会报错。

因为对于动态库来说:

编译时的搜索路径为gcc

运行时的库搜索路径为os

两个路径可以一样,但对于自定义的库,需要用户即告诉编译器又告诉操作系统。

如果不想每次都手动去链接使用,有以下四种方法来解决:

1.将自定义库和cp拷贝到系统库(/lib64),既可以支持编译又可以支持运行。

2.使用环境变量

系统程序运行时 ,动态库查找的辅助路径,将不在系统默认搜索路径下的库路径,添加到LD_LIBRARY_PATH中。

 3.在系统库下建立软链接

4.通过系统的配置文件路径的方案

推荐第一种和第三种方法,较为方便快捷。

当自定义静态库和动态库都存在且在同一路径下时 ,./运行时优先默认使用动态库。

如果非要静态链接必须使用static选项,如果只能对该库进行静态链接,但是程序不一定整体是静态链接的。

如果只提供动态库,默认只能动态链接,非得静态链接,会发生链接报错。


http://www.ppmy.cn/news/1416223.html

相关文章

python知识点汇总(十一)

python知识点总结 1、当Python退出时&#xff0c;是否会清除所有分配的内存&#xff1f;2、Python的优势有哪些&#xff1f;3、什么是元组的解封装4、Python中如何动态获取和设置对象的属性&#xff1f;5、创建删除操作系统上的文件6、主动抛出异常7、help() 函数和 dir() 函数…

鸿蒙OS开发学习:【第三方库调用】

介绍 本篇Codelab主要向开发者展示了在Stage模型中&#xff0c;如何调用已经上架到[三方库中心]的社区库和项目内创建的本地库。效果图如下&#xff1a; 相关概念 [Navigation]&#xff1a;一般作为Page页面的根容器&#xff0c;通过属性设置来展示页面的标题、工具栏、菜单。…

[RK3399 Linux] 使用ubuntu 20.04.5制作rootfs

一、ubuntu base ubuntu base是用于为特定需求创建自定义映像的最小rootfs,是ubuntu可以运行的最小环境。 1.1 下载源码 下载ubuntu-base的方式有很多,可以从官方的地址:ttp://cdimage.ubuntu.com/ubuntu-base/releases。 也可以其它镜像地址下载,如清华源:https://mi…

java方法引用和Stream流

方法引用 一种简化代码的语法糖,用于直接引用已经存在的方法 是lambda表达式的一种简化形式,用于方法的参数传递 可以简化代码,提高代码的可读性和可维护性 当调用接口的抽象方法时,实际调用的是被引用的方法 方法引用的形式 1,静态方法引用: 类名::静态方法名 引用类中…

2万字长文:MySQL面试题及参考答案(持续更新)

MySQL作为最受欢迎的关系型数据库之一,无论是在面试中还是在实际工作中,对MySQL的深入理解和应用都是必不可少的。本文将为您提供一系列常见的MySQL面试题及其参考答案,帮助您在面试中脱颖而出,同时也为您的数据库实践提供指导。 目录 1. 什么是数据库事务?事务的ACID特…

【Docker】docker快速安装部署fastdfs的镜像详细记录

部署nacos的docker镜像 第一步&#xff1a; 获取fastdfs镜像1、查看镜像列表2、创建本地映射文件夹 第二步&#xff1a;运行镜像1.使用docker镜像构建tracker服务2.使用docker镜像构建Storage服务3.Storage服务中默认安装了Nginx服务4.如果需要修改storage则配置则进到以下目录…

Java基础语法(二十五):线程同步和互斥

文章目录 目录 文章目录 前言 什么是线程同步和互斥&#xff1f; Java中的线程同步和互斥 实现线程同步的方式 实现线程互斥的方式 代码示例 总结 前言 在多线程编程中&#xff0c;线程同步和互斥是至关重要的概念。特别是在Java中&#xff0c;多线程的使用非常普遍&…

Go语言中如何实现多态

完整课程请点击以下链接 Go 语言项目开发实战_Go_实战_项目开发_孔令飞_Commit 规范_最佳实践_企业应用代码-极客时间 在Go语言中&#xff0c;虽然没有像其他面向对象语言&#xff08;如Java或C&#xff09;中那样的显式的类继承和多态机制&#xff0c;但通过接口和方法的组合…