Linux库文件

静态库和动态库

1、什么是库文件

库文件就是计算机上的一种文件,也相当于一种代码仓库,可以供他人直接使用的变量、函数以及类。库是一类特殊的程序,编写库的程序与编写一般程序的差别不大,但是库不可单独运行。库文件主要功能是代码保密以及方便部署。
库文件可区分为静态库以及动态库,其中:静态库是在程序的链接阶段被复制在程序中;动态库则是在链接阶段不会复制在程序中,而是在运行时由系统动态加载到内存中供程序调用。

2、静态库

2.1库文件命名规则

Linux : libxxx.a
	--lib : 固定前缀
	--xxx : 库文件名
	--.a : 固定后缀
windows : libxxx.lib

2.2静态库制作

1、 gcc获取.o文件 : gcc -c main.c ,编译 main.c 文件,并生成目标文件 main.o 
		--gcc: GNU Compiler Collection 的缩写,是一个开源的编译器套件,用于编译和链接程序。
		-- -c : 是 gcc 的选项之一,表示进行编译但不进行链接。它告诉编译器只生成目标文件,而不生成可执行文件。
		--main.c: 是需要编译的源文件名,这里假设 main.c 是你的源代码文件。
2、 将 .o 文件打包制作成库 : ar rcs libxxx.a xxx.o xxx.o
		--ar: 是一个用于创建、修改和提取静态库文件(Archive 文件)的工具。
		--rcs: 是 ar 命令的选项参数,具体含义如下:
			r: 将文件插入到归档文件中。如果文件已经存在于归档文件中,则先删除原文件再插入。
			c: 创建归档文件。如果归档文件不存在,则创建一个新的归档文件。
			s: 更新归档文件的索引信息。这个选项通常用于更新归档文件的索引,以确保归档文件中包含每个对象文件的索引信息,这样可以加快链接过程。
		--libxxx.a : 创建的静态库名
		--xxx.o : 需要插入到静态库中的目标文件

3、动态库

3.1命名规则

Linux : libxxx.so
		--lib : 固定前缀
		--xxx : 动态库的名字
		--.so : 固定后缀
windows : libxxx.dll

3.2动态库制作

1、gcc 得到 .o 文件,得到和位置无关的代码 : gcc -c –fpic/-fPIC a.c b.c
	-- -fpic 或 -fPIC: 这两个选项是用来告诉编译器生成位置无关代码。
2、gcc 得到动态库 : gcc -shared a.o b.o -o libxxx.so
	-- -shared: 是 gcc 的选项之一,表示生成一个共享库(shared library)。共享库也被称为动态链接库(Dynamic Link Library,DLL),它包含可在运行时加载到内存中并被程序动态链接的代码和数据。
	--a.o b.o: 是要链接的目标文件列表,通常是使用 -fpic 或 -fPIC 选项编译得到的位置无关代码的目标文件。
	-- -o libxxx.so: 指定生成的动态库文件的名称为 libxxx.so

4、工作原理

  • 静态库 : GCC在进行链接时,将静态库中的代码打包至可执行程序中
  • 动态库 : GCC在进行链接时,动态库中的代码不会打包至可执行程序中
  • 可执行程序在启动之后,动态库将动态加载至内存,可通过 ldd 命令检查动态库依赖关系
  • 定位动态库文件方法:
    - 1.先搜索 elf 文件的 DT_RPATH 段
    - 2.搜索环境变量 LD_LIBRARY_PATH , 设置 LD_LIBRARY_PATH 环境变量来指定动态链接器的搜索路径 : export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/nowcoder/Linux/lesson03/04_lib/library/lib 。 这样设置后,动态链接器在运行时会优先搜索 /home/nowcoder/Linux/lesson03/04_lib/library/lib 目录中的共享库。
    - 3.使用 ldconfig 更新共享库缓存 , ldconfig 命令用于更新动态链接器的运行时连接配置,它会重建 /etc/ld.so.cache 文件,其中包含了动态链接库的缓存信息。如果你安装了新的共享库或者修改了共享库路径,可能需要运行sudo ldconfig 命令来更新系统的共享库缓存,以确保新的共享库可以被正确加载。
    - 4.系统默认搜索路径 :Linux系统在链接共享库时会搜索一组默认的路径,这些路径通常包括: /lib/,/usr/lib 目录。
    - 5.指定额外的共享库路径 : 如果共享库不在默认的搜索路径下,可以使用 -L 选项来指定额外的搜索路径。
gcc myprogram.o -o myprogram -L/path/to/custom/lib -lmath
	-- myprogram.o: 是编译生成的目标文件。
	-- -o myprogram: 指定输出文件为 myprogram。
	-- -L/path/to/custom/lib: 指定额外的库文件搜索路径,这里假设 /path/to/custom/lib 是 libmath 库所在的路径。
	-- -lmath: 指定要链接的库为 libmath。gcc 将会在指定的路径和系统默认路径下查libmath.so 或 libmath.a 文件,并将其链接到最终的可执行文件 myprogram 中。
这样,你就可以成功编译并链接一个依赖于 libmath 数学库的程序 myprogram。

5、两者区别

在这里插入图片描述

静态库

在这里插入图片描述

优点
  • 静态库打包到应用程序中加载速度快
  • 因为静态库在编译时完全嵌入到可执行文件中,所以发布程序时无需提供静态库,移植方便
缺点
  • 消耗系统资源 : 静态库会将所有代码和数据都复制到可执行文件中,这意味着如果多个程序使用了同一个静态库,每个程序都会包含一份完整的库副本。这会导致可执行文件体积变大,尤其是当静态库较大时,会占用大量磁盘空间。
  • 浪费内存、内存使用效率低 : 当多个程序同时运行且使用同一个静态库时,操作系统需要为每个程序分配该静态库的内存空间。相比之下,共享库可以在内存中只加载一份,并由多个程序共享,节省内存使用。
  • 更新、部署、发布麻烦 : 如果静态库更新了,所有依赖它的程序都需要重新编译以使用更新后的版本。这可能会增加维护成本,尤其是在需要频繁更新或修复 bug 的情况下。

动态库

在这里插入图片描述

优点
  • 可以实现进程间资源共享 :动态库可以被多个应用程序共享使用,因为它们在内存中只需加载一次,不同的应用程序可以共享同一个动态库的实例,从而节省内存。
  • 动态加载:动态库在程序运行时才会被加载,而不是编译时静态链接到可执行文件中。这使得程序可以根据需要动态加载和卸载库,从而实现更灵活的组件化和模块化设计。
  • 更新管理:更新动态库比更新静态库更为方便,因为只需替换库文件即可,无需重新编译整个程序。这可以减少更新对程序其他部分的影响,并简化版本管理。
缺点
  • 加载速度比静态库慢:相对于静态库,动态库在运行时需要进行加载和链接操作,这可能会导致一些额外的运行时性能开销。
  • 发布程序时需要提供依赖的动态库 : 使用动态库需要确保目标环境中有正确的库版本,并在部署时处理好依赖关系和库路径设置,以确保程序正常运行。
  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值