Linux---动静态库的原理和实现

动静态库的原理和实现

  • 1. 磁盘
  • 2. 文件系统
  • 3. inode
  • 4. 软硬链接
  • 5. 认识并制作动静态库
    • 5.1 静态库
      • 5.1.1 静态库的实现
      • 5.1.2 静态库的使用
    • 5.2 动态库
      • 5.2.1 动态库的实现
      • 5.2.2 动态库的使用

1. 磁盘

Linux---动静态库的原理和实现_第1张图片
磁盘的描述性结构
Linux---动静态库的原理和实现_第2张图片
盘面、柱面、扇区就能定位到我想找的文件。但是对于操作系统来说,他不可能还要关心这里问题,所以把物理的地址转化为了对于逻辑数组的管理。
Linux---动静态库的原理和实现_第3张图片

2. 文件系统

可以理解为每一个盘面就是一个分区,但是这个分区还是太大了,所以还需要分成很多的块组(Block group),那么管理好一个块组类比于其他的,就能把所有的块组都管理好,也就可以把这个分区管理好了。
Linux---动静态库的原理和实现_第4张图片
这个为磁盘文件系统图

  1. Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。
  2. 超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。SuperBlock的信息被破坏,可以说整个文件系统结构就被破坏了
  3. GDT(Group Descriptorable):块组描述符,描述块组属性信息(这一个块的具体信息)
  4. 块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
  5. inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
  6. inode Table节点表:存放文件属性如文件大小,所有者,最近修改时间等(一个文件只有一个inode)
  7. Date blocks数据区:存放文件内容(一个文件可能会有多个blocks)

3. inode

存放文件的属性

inode中必须包含Date blocks对应的映射关系,inode里面有一个数组,存放着和这个文件相关的blocks,拿着这个数组里存放的下标,就可以找到这个文件所有的blcoks。
在这里插入图片描述
目录也是文件=inode+数据块(文件名:inode id)

4. 软硬链接

硬链接
ln new.txt h_link 就会生成一个h_link的新文件,会发现这个文件和你的new.txt文件的inode是一样的。 所以硬链接不是一个独立的文件

在这里插入图片描述
那么硬链接到底是什么呢?
文件名和inode对应的映射关系的个数。
Linux---动静态库的原理和实现_第5张图片
此时不管你打开h_link还是new.txt文件,他们操作的都是通过同一个inode找到的文件。
软连接
ln -s log.txt link 生成一个link -> log.txt 的文件,那么和原本的log.txt有什么区别呢?
在这里插入图片描述

会发现生成的软连接有一个inode和原本的log.tet文件的inode是不一样的。所以软连接是一个独立的文件

如果项目比较深的话,可以把可执行程序直接的放在bin目录下面,那么你就可以不用在一步步深入目录去寻找了,而是直接的./start.link就可以运行。
Linux---动静态库的原理和实现_第6张图片

5. 认识并制作动静态库

Linux---动静态库的原理和实现_第7张图片

5.1 静态库

对于静态库的编写只需要在Makefile中的gcc -o $@ $^ -static加static就好了,就会生成静态库文件,对比于静态库和动态库生成的文件,静态库生成的文件体积非常的大(占用硬盘的资源),当你的程序中有多条printf语句的时候,那么就会出现多份从C库中拷贝过来的printf的实现方法(占用内存的资源
在这里插入图片描述
静态库的原理:直接将对应的代码拷贝进bin,体积比较大,bin的可移植性强
Linux---动静态库的原理和实现_第8张图片

5.1.1 静态库的实现

首先要明白,我自己制作的库目的是为了去给别人直接的使用,那么所交给别人的库就需要包含

  1. 一批头文件:有什么方法可以使用,接口参数是什么意思。
  2. 一个或多个库文件:具体的实现,供我们动静态链接

静态库粗暴一些就可以理解为:把我的代码生成的.o文件都进行打包,改名为.a
在这里插入图片描述
把所有的.c文件都进行gcc -c xxxxxx.c 会生成同名的.o文件
Linux---动静态库的原理和实现_第9张图片
把所有的.o文件都进行打包,会生成一个.a文件 ar -rc libmymath.a myadd.o mysub.o mymul.o mydiv.o
ar是gnu归档工具,其中rc表示(replace and create)
Linux---动静态库的原理和实现_第10张图片
③我要把我打包好的静态库和头文件给别人使用,创建一个mylib的文件,在mylib里面放着一个include文件,用来存储我的所有的头文件,lib文件用来存储我所打包好的静态库
在这里插入图片描述
在这里插入图片描述

5.1.2 静态库的使用

我把我的库打包好给别人使用,但是会发现,即使mylib在当前目录下面可是依旧会报错,说明默认是找不到的

#include
#include
#include

int main()
 {
  	 int x = 10;
     int y = 5;
     printf("add : %d\n",MyAdd(x,y));
     printf("sub : %d\n",MySub(x,y));

     return 0;                                                                                                                                                                           
}

Linux---动静态库的原理和实现_第11张图片

  1. -I :指针自定义头文件路径
  2. -L:指定自定义库路径
  3. -l:指定库名

Linux---动静态库的原理和实现_第12张图片
在这里插入图片描述
其实我们还可以把对应的头文件和库文件放在对应的系统里面,在Makefile中要默认还是带上-l mymath这个选项就行,但是并不建议这样去使用,因为你这样做会污染原本的头文件池和库文件池。

5.2 动态库

并不把库中的代码给我们拷贝过来,所以生成的可执行程序的体积相对较小,但是非常的依赖C库,且在运行的时候才加载,可以只有一份
动态库的原理:
Linux---动静态库的原理和实现_第13张图片

5.2.1 动态库的实现

  1. shared: 表示生成共享库格式
  2. fPIC:产生位置无关码(position independent code)
  3. 库名规则:libxxx.so

Linux---动静态库的原理和实现_第14张图片
Linux---动静态库的原理和实现_第15张图片
发布的版本:
Linux---动静态库的原理和实现_第16张图片
make output,就会看见一个mylib的文件
在这里插入图片描述

5.2.2 动态库的使用

此时使用一个我所创建的动态库。
在这里插入图片描述
Linux---动静态库的原理和实现_第17张图片
然后make,你就会发现可以生成可执行程序,但是运行不了。

在这里插入图片描述
原因是找不到库,那我已经指定了我的库搜索路径了呀,为什么还找不到呢?是因为编译器可以找到这个库的位置,但是操作系统找不到,所以需要改环境变量,LD_LIBRARY_PATH ldd 文件用来查看文件所依赖的库

export LD_LIBRARY_PATH=/home/wzy/lesson_19/new/mylib/lib改完之后,就可以运行了
在这里插入图片描述

你可能感兴趣的:(Linux)