一、软硬链接
一个硬盘分区里会划分为很多个block,文件管理则是对这些block的管理
- inode Table:每个文件都有一个inode编号,对应编号里存放着文件属性的相关信息
- Data blocks:文件的inode中会说明该文件的主体内容存放在哪个data block块中
- inode map:inode块的位图,0标识没被占用,1表示被占用
- block map:data block块的位图,0标识没被占用,1表示被占用
1、文件的创建与删除过程
假设在目录A下:
- 创建一个test.txt文件,首先在inode位图中找一个为0的位置将其改为1,在该位置index对应的inode块中填入文件属性相关信息,再在data block位图中找到一个为0的位置,将文件主体内容填进还位置index对应的data block块中,最后在A目录下,简历一个inode块编号<->文件名的映射项。
- 删除一个abc.c文件,首先通过目录A中的inode块编号<->文件名的映射项,将该inode编号在inode位图中的位置由1变为0,然后再目录A中删除该inode块编号<->文件名的映射项。
2、软链接与硬链接
可以通过 ls -i查看到inode编号
stat查看文件的inode信息
- 软链接
命令:ln -s <需要被链接的文件> <软链接名>
软链接(符号链接):创建一个新的文件,该文件有自己的inode编号和data block,只是data block中存放的是链接的文件的地址
- 硬链接
命令:ln <需要被链接的文件> <硬链接名>
硬链接:在目录中新建一个inode块编号<->文件名的映射项,inode块编号是需要被链接的文件的inode块编号,文件名是硬链接名。
删除链接推荐用 unlink,不太推荐直接 rm
二、动静态库
ldd <可执行文件> :查看可执行程序的链接方式(Linux下生成的可执行文件,默认动态链接,gcc后加上-static生成的是静态链接)
file <可执行文件>:可以查看动静态方式
1、静态库
静态库指使用该库的代码,在链接时会把代码链接到可执行的目标文件中。
特点:体积大,浪费资源,不依赖于库,库丢失也可以跑
打包静态库:
1、有Add.c、Add.h、Sub.c、Sub.h,将*.c编译汇编成.o(gcc -c Add.c -o Add.o)
2、ar -rc <库的名字;libmymath.a;lib是前缀、.a是后缀一定要有,中间的mymath是这个库的名字> <需要打包的文件1.o> <需要打包的文件2.o>(ar是gnu归档工具,rc表示replace & create)
3、最好将库文件(.a/.so)和头文件放到一个文件夹中
4、使用库
gcc main.c -o main -I ./static_lib -L ./static_lib -lmymatn -static
-I:让gcc在除了默认路径和当前路径下,还在哪个路径下找头文件
-L:让gcc除了在默认路径和当前路径下,还在哪个人路径下找库文件
-l(L小写):让gcc知道找哪个库文件
linux头文件的默认路径:/usr/include/
linux库文件的默认路径:/lib64/
将头文件和库文件拷贝到默认路径下,就可以不用带-I和-L了,不过最好别这么干
思考:为什么C语言编译时,没有明显使用过-I、-L、-l?
因为库文件和头文件在默认路径下;gcc编译C语言的,默认链接libc
2、动态库
运行时遇到调用的代码部分,才动态去链接动态库中的代码,实现功能后再返回来执行原来的可执行程序。
特点:体积小,节省资源,一旦库丢失,bin不可以执行
打包动态库:
注意生成.o时gcc选项,要加上位置无关码-fPIC
生成.so时gcc选项,要加上-shared
1、
libmymath.so:Add.o Sub.o
gcc -shared -o $@ $^
Add.o:Add.c
gcc -fPIC -c -o $@ $^
Sub.o:Sub.c
gcc -fPIC -c $^ -o $@
2、将库文件(.a/.so)和头文件放到一个文件夹中
3、如何使用动态库
gcc main.c -o main -I ./lib/ -L ./lib/ -lmymath
直接这样使用会出错,因为gcc找到了,但是程序运行时动态链接时,系统找不到
4、有三个方法解决上述问题
1、将.so所在路径倒入LD_LIBRARY_PATH(推荐)(一次性的)
2、将.so拷贝到系统共享库文件下
3、 ldconfifig 配置/etc/ld.so.conf.d/
ldconfig更新(非一次性的,但是不建议)
root下,建立一个自己的.conf(名字随便取),将.so路径放进去