🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
文章目录
- 一、创建软硬链接
- 二、软硬链接
- ①软链接
- ②硬链接
- ③硬链接的用处
- ④软硬链接的区别
- 三、库的作用
- ①库与为什么用库
- ②动静态库的加载过程
- 四、动静态库
- ①静态库 .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高速编译器库名就可以找到。