Linux软硬链接与动静态库

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

文章目录

  • 一、创建软硬链接
  • 二、软硬链接
    • ①软链接
    • ②硬链接
    • ③硬链接的用处
    • ④软硬链接的区别
  • 三、库的作用
    • ①库与为什么用库
    • ②动静态库的加载过程
  • 四、动静态库
    • ①静态库 .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
Linux软硬链接与动静态库_第1张图片
删除一个文件,除了可以用rm之外,unlink也是可以删除的

二、软硬链接

①软链接

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

②硬链接

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

Linux软硬链接与动静态库_第2张图片
可以发现testLink1.txt和hard.link的inode编号是一样的,所以只是建立了文件名和inode的映射关系
Linux软硬链接与动静态库_第3张图片
我们此时把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
Linux软硬链接与动静态库_第4张图片

④软硬链接的区别

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

三、库的作用

①库与为什么用库

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

②动静态库的加载过程

静态链接,链接静态库,会在链接阶段将静态库中需要使用的指令代码单独写进自己的可执行程序,运行时无依赖,加载速度快,但就是代码冗余,而且静态库变了之后需要重新编译生成可执行程序

动态链接,链接动态库,是运行时库,在运行时才加载进内存,加载的时候各个程序根据加载的起始地址计算使用到的内部函数和变量的地址,这些地址都映射到了程序的进程地址空间的共享区,在共享区建立了映射,因为可以这样做,所以可以被多个程序建立映射,因此动态库又称作共享库,速度慢,有依赖,但是不冗余

四、动静态库

如果把头文件(看函数声明)目标文件给别人用,那么也能用,但是目标文件此时就有一堆,用起来难受,而且如果弄丢一个就更难受。
Linux软硬链接与动静态库_第5张图片

①静态库 .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.o
	ar -rc libhello.a mymath.o myprint.o

Linux软硬链接与动静态库_第6张图片
本质上就是打包

②使用静态库

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

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

Linux软硬链接与动静态库_第7张图片
Linux软硬链接与动静态库_第8张图片
但是当我将头文件和静态库都拷贝到系统目录之后,为了编译main.c还是报错呢?因为我们自己写的库是第三方库,编译的时候就需要告诉编译器我们用的什么库库的名字需要去掉前缀和后缀

gcc main.c -l hello //即可

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

2.直接使用该库

Linux软硬链接与动静态库_第10张图片
没有安装库,当然找不到,因为我们调用库的时候,首先会在当前目录下找,找不要就会在特定目录下搜索,也就是/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不以文件名来区分文件

Linux软硬链接与动静态库_第11张图片
然后将生成的这个动态库也放到hello/lib/

④使用动态库

1.直接使用

Linux软硬链接与动静态库_第12张图片

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高速编译器库名就可以找到。
在这里插入图片描述

你可能感兴趣的:(Linux,linux)