1.3 静态库与动态库制作
1.3.1 介绍
-
库文件
是计算机上的一类文件,可以把它当作是一个代码仓库,可以为程序提供变量、函数和类。 -
库文件与可执行文件差别不大,但是库文件不能直接运行。
-
库分为两种:
静态库
、动态库
(共享库),静态库在编译时写入可执行文件,动态库在执行时读入内存。 -
库具有
代码保密
,部署与分发方便
的优势。
1.3.2 静态库
- 命名规范:
Linux
:libxxx.a,Windows
:libxxx.lib
静态库制作
首先自行安装ar
工具。
假设我们的项目包括:main.c
,head.h
,add.c
,sub.c
,mul.c
,div.c
。
head.c
文件位于include
目录下,add.c
,sub.c
,mul.c
,div.c
位于lib
目录下。
$ gcc -c add.c sub.c mul.c div.c // 生成目标代码: add.o sub.o mul.o div.o
$ ar src libcalc.a *o // 建立静态库. s-索引, r-将文件插入备存文件中, c-建立备存文件, 库文件名: libcalc.a
$ gcc main.c -o main -L . -l calc // 打包程序(即使静态库在同一目录, 也需要-L)
静态库优缺点
-
优点
-
静态库打包在应用程序中,加载速度快。
-
静态库提供单一文件,移植方便。
-
适用于小体积库。
-
-
缺点
- 消耗系统资源,重复占用内存。
- 更新、部署麻烦。
1.3.3 动态库
- 命名规范:
Linux
:libxxx.so,Windows
:libxxx.dll
动态库制作
$ gcc -c -fpic add.c sub.c mul.c div.c // 生成目标代码: add.o sub.o mul.o div.o, 目标代码与位置无关
$ gcc -shared *.o -o libcalc.so // 建立动态库, 库文件名: libcalc.so
$ gcc main.c -o main -L . -l calc // 打包程序(即使静态库在同一目录, 也需要-L)
注意:此时启动程序./test
将出现file not found
错误,因为动态库路径没有被找到。
动态库路径搜索原理
-
动态库在编译阶段仅写入描述信息,在程序运行时载入内存。
-
当系统需要载入动态库时,通过库名与绝对路径定位动态库,绝对路径由动态载入器查找。
-
对于
elf
格式的应用程序,查找优先级为:DT_RPATH
段 → \to → 环境变量LD_LIBRARY_PATH
→ \to →/etc/ld.so.cache
文件 → \to →/lib
与/usr/lib
目录。
添加动态库路径
-
方法一:配置环境变量
注:
LD_LIBRARY_PATH
跟随终端,重启终端将会重置。
$ cd . // 切换至 libcalc.so 所属目录, 此处为 . , 即为打包时 -L 目录
$ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD // 向 LD_LIBRARY_PATH 追加 PWD 路径, PWD 也是环境变量为当前目录
$ cd . // 切换至 main 所属目录, 此处为 .
$ ldd main // 检查动态库依赖关系, 如正确操作, 无 not found
-
方法二:配置
/etc/ld.so.cache
文件注:
/etc/ld.so.cache
为二进制文件,无法直接修改。
$ sudo vim /etc/ld.so.conf // 编辑 /etc/ld.so.conf 文件需要管理员权限
// 在末行添加 库绝对路径, 保存并退出
$ sudo ldconfig // 重新配置 ld.so.cache 文件, 实际上将 ld.so.conf 加载为 ld.so.cache 文件
$ ldd main // 检查动态库依赖关系, 如正确操作, 无 not found
-
方法三:配置
~/.bashrc
文件(不推荐)注:
~/.bashrc
为终端启动配置,因此配置结束需重启终端。
$ vim ~/.bashrc // 编辑 .bashrc 文件
// 在末行添加 export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库绝对路径, 保存并退出
// 重启终端并切换至 main 所属目录
$ ldd main // 检查动态库依赖关系, 如正确操作, 无 not found
-
方法三:添加至
/lib
或/usr/lib
目录(不推荐)注意:容易意外覆盖重要文件
$ mv libcalc.so /lib // 或 mv libcalc.so /usr/lib
$ ldd main // 检查动态库依赖关系, 如正确操作, 无 not found
动态库优缺点
- 优点
- 实现系统资源共享。
- 更新、部署方便。
- 动态库加载时刻可控制。
- 适用于大体积库。
- 缺点
- 加载速度相比于静态库较慢。
- 发布程序需提供相关库。