Linux软硬链接与动静态库

news/2024/11/8 14:55:40/

🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
在这里插入图片描述

文章目录

  • 一、创建软硬链接
  • 二、软硬链接
    • ①软链接
    • ②硬链接
    • ③硬链接的用处
    • ④软硬链接的区别
  • 三、库的作用
    • ①库与为什么用库
    • ②动静态库的加载过程
  • 四、动静态库
    • ①静态库 .a
    • ②使用静态库
      • 1.将这个库拷贝到系统的库路径下
      • 2.直接使用该库
    • ③动态库 .so
    • ④使用动态库
      • 1.直接使用
      • 2.系统的环境变量 LD_LIBRARY_PATH
      • 3.修改配置文件
      • 4.在lib64建立动态库的软链接

一、创建软硬链接

ln 文件名  文件名//ln testLink1.txt hard.link//硬链接
ln -s 文件名 文件名//软连接

ln即为link,所以也可以用link/link -s
在这里插入图片描述
删除一个文件,除了可以用rm之外,unlink也是可以删除的

二、软硬链接

①软链接

在另外的路径下创建的可执行程序,我想去执行一下,那么就要用绝对路径或者相对路径或者说配置环境变量,但是如果这个路径特别特别深,那么每次都要去写绝对/相对路径的时候就比较麻烦这时候,软链接就发挥作用了,在当前路径下进行软链接==ln -s xxx路径 myexe可执行文件名
然后直接运行这个软链接就可以跑了,所以,软链接就相当于Windows下的快捷方式一样,就可以理解为:软链接文件的内容,是指向的要找的那个文件对应的路径

②硬链接

创建硬链接,不是真正的创建新文件,因为硬链接没有独立的inode编号,但是他有inode编号,用的是其他文件的内容和属性
创建硬链接就是在指定目录下,建立了文件名和指定inode编号的映射关系(作用可以看看上一篇文件系统和inode),也就是说硬链接仅仅是起了一个别名

在这里插入图片描述
可以发现testLink1.txt和hard.link的inode编号是一样的,所以只是建立了文件名和inode的映射关系
在这里插入图片描述
我们此时把testLink1.txt删掉,我们看到,hard.link仍然还在(inode还在,说明文件还在),那么此时说明只是把目录data blocks中testLink1.txt和inode的映射关系删掉了。(文件系统与inode中讲到)我们可以看到,有一个数字从2变成了1,这个数字就是硬链接数,硬链接数在inode中就是一个计数器,来记录有多少个文件名和这个inode有映射关系(引用计数),当我们删掉一个文件的时候,只是把硬链接数-1,(也就是删掉了一个映射),当硬链接数变为0的时候,这个文件才真正被删除

③硬链接的用处

创建一个普通文件,它的硬链接数是1,但是当我们创建了一个空目录,它的硬链接数是2
在这里插入图片描述

这是因为,首先,建立了一个目录文件,这个目录文件本身就和inode编号有一组映射关系,其次,一个空目录里面,默认就有 ... 这两个文件,而这个.就代表的是当前目录下,也就是dir的硬链接,通过inode编号我们可以看出来
在这里插入图片描述
而当我们再在dir下创建一个目录d1,那么d1中还有一个..指向了dir目录文件,所以这时,dir目录文件的硬链接数是3
在这里插入图片描述

④软硬链接的区别

区别就是软链接有自己独立的inode,他像是一个快捷方式,软链接data block存储的是被链接文件的地址。而硬链接没有自己独立的inode,它只是当前文件名和inode的一种映射,就像是给文件取别名,同一个inode编号的不同映射

三、库的作用

①库与为什么用库

1.什么是库?库是一段编译好的二进制代码
2.为什么要用库?
①别人提供,不想让我们看到细节,只给我们使用方法(头文件)和编译好的库,再给一个使用手册或者官方文档,程序员自己搜,工作之间完全解耦
②某些不会进行大的改动的代码,会打包成库,因为是编译好的,所以节省时间,用的时候link一下就可以了

②动静态库的加载过程

静态库在链接的时候会将二进制代码拷贝一份过来,复制到目标程序里。静态库的好处很明显,就是目标程序没有外部依赖,直接就可以运行,但是缺点就是会增大目标文件的体积,而且大的还不少

动态库与静态库相反,并不会拷贝到目标文件中,而目标文件中只会存储指向动态库的引用,等到程序运行时,动态库才会分批载入内存。而动态库是在进程地址空间的共享区的,它加载一次可以被多个进程使用,所以也被称为共享库,根据以上特性,所以比静态链接的目标文件小很多,动态库的优点就在于此,而且因为运行时才载入,所以我们不用重新编译就可以替换动态库,但是动态载入会带来一部分性能损失,使用动态库也会使得程序依赖于外部环境。如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行。

四、动静态库

如果把头文件(看函数声明)目标文件给别人用,那么也能用,但是目标文件此时就有一堆,用起来难受,而且如果弄丢一个就更难受。
在这里插入图片描述

①静态库 .a

多个目标文件.o进行归档archive(放在一起),就形成了静态库
库的前缀必须是lib,静态库的后缀必须是.a,动态库的后缀必须是.so

ar -rc libhello.a mymath.o myprint.o
//-r是replace替换,-c是create创建

archive -rc的makefile自动化

libhello.a:mymath.o myprint.oar -rc libhello.a mymath.o myprint.o

在这里插入图片描述
本质上就是打包

②使用静态库

1.将这个库拷贝到系统的库路径下

文件的系统路径: /usr/include
库的系统路径 /usr/lib64或者/lib64,两个都可以

在这里插入图片描述
在这里插入图片描述
但是当我将头文件和静态库都拷贝到系统目录之后,为了编译main.c还是报错呢?因为我们自己写的库是第三方库,编译的时候就需要告诉编译器我们用的什么库库的名字需要去掉前缀和后缀

gcc main.c -l hello //即可

在这里插入图片描述
这样即可使用,把库拷贝到系统目录下,这个过程就叫做库的安装,所谓的安装,也就是拷贝,无论是在Linux还是在Windows,但是呢,自己写的第三方库并没有经过可靠性验证,所以并不建议把自己写的库安装在系统目录下,所以赶紧删掉,这就是库的卸载

2.直接使用该库

在这里插入图片描述
没有安装库,当然找不到,因为我们调用库的时候,首先会在当前目录下找,找不要就会在特定目录下搜索,也就是/usr/lib64或者/lib64。

//找头文件和库
gcc main.c -I ./hello/include/-L ./hello/lib/ -l hello
//第三方库,告诉库名//-I是include
//-L是library     
//-l表示去链接某个库,因为./hello/lib/下的库
//可能不止一个,所以要指定

③动态库 .so

静态库有它自己的地址空间,因为每一个进程都需要拷贝一份静态库,必须要拷贝到可执行的特定位置,才能够被我访问到,这叫做与地址有关,静态库是一种绝对编址的方案。

动态库采用的是相对编址的方案,动态库是在进程地址空间的共享区的,而只需要拿到动态库在物理内存当中的起始位置和偏移量,就可以找到,一个动态库可以被多个进程共享

gcc -fPIC -c mymath.c -o mymath.o
//-fPIC这个选项就是形成一个与位置无关的二进制目标文件
gcc -shared myprint.o mymath.o -o lobhello.so
//-shared 区分是生成可执行程序还是动态库,因为linux不以文件名来区分文件

在这里插入图片描述
然后将生成的这个动态库也放到hello/lib/

④使用动态库

1.直接使用

在这里插入图片描述

gcc main.c -I ./output/include/ -L ./output/lib/ -l hello

当我们既有动态库又有静态库libhello.a libhello.so
那么默认会进行动态链接(用dll来查看可以看出),只有静态库的话就链接静态库,如果两个都有,编译的时候添加 -static选项来进行静态链接

在这里插入图片描述

2.系统的环境变量 LD_LIBRARY_PATH

这个环境变量就是库加载时候的搜索路径

echo $LD_LIBRARY_PATH进行环境变量的查看
export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:路径  进行环境变量的修改

因为这个环境变量是内存级的环境变量,下次登录的时候环境变量会从配置文件中重新获取,所以,我们这样配置的环境变量下次登录就没了

3.修改配置文件

在这里插入图片描述
这个路径保存的是允许可以自定义配置搜索库路径的永久解决方案,具体做法就是touch一个xxx.conf然后把搜索路径粘上去,保存之后idconfid就生效了。建议不要随便改配置文件

4.在lib64建立动态库的软链接

ln -s 库的路径 /lib64/软链接的文件名

建立一个软链接,然后系统目录下就可以找到,因为是第三方库,所以-l高速编译器库名就可以找到。
在这里插入图片描述


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

相关文章

[附源码]Python计算机毕业设计Django海滨学院学生大创项目申报与审批系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

[C语言]指针初阶

[C语言]指针初阶 文章目录[C语言]指针初阶1.指针def:2.指针变量:3.指针和内存的关系:4.指针和指针类型:4.1指针类型:5.指针-整数:6.指针的解引用:7.野指针:7.1成因:7.2如何规避野指针:8.指针运算:8.1指针-整数&#xf…

windows git

git | 安装 网址 https://git-scm.com/downloads https://gitforwindows.org 教程 Git详细安装教程 git连接github远程仓库 git | 设置用户名 邮箱 打开 Git Bash Here 输入: git config --global user.name ‘用户名’ git config --global user.email ‘邮箱’ …

怎么进行视频配音?建议收藏这些配音方法

最近我的朋友向我求助,他想要自己制作一个视频,但是视频里面有些片段需要配音,可是他又不想用自己的声音来配音。一方面担心容易NG,需要录制很多遍,会浪费较多的时间;另一方面是,如果视频录制和…

[附源码]Node.js计算机毕业设计辅导员班级量化管理系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

理解DDR Part 1

DDR x4 x8 x16 x4 x8 x16 指的上图黑色的chip输出的位宽,正常的DDR bus width 需要64bit,所以 chip width x4 x8 x16 黑色chip数量 16 8 4 上图是最常见的x8,也就有8个黑色的chip颗粒。x16的性能和x8的性能相比怎么样呢? 更差&…

HDLBits练习汇总-12-时序逻辑设计测试--更多电路

rule90(一维元胞自动机) Rule_90是一个具有有趣属性的一维元胞自动机。 规则很简单。有一个一维单元格数组(开或关)。在每个时间步长,每个像元的下一个状态是像元的两个当前邻居的异或。下表是更详细地表达此规则的方…

C# 数组及集合

一 数组 声明: int [] a; int [,]b; 分配空间: anew int[5]; bnew int[4,5]; 二 集合类 System.Collections命名空间; 数组列表ArrayList 相当于动态数组,实现IList; 哈希表 Hashtable 相当于键/值的集合,实现IDict…