目录
[静态库(Static Library)](#静态库(Static Library))
[动态库(Dynamic Library)](#动态库(Dynamic Library))
[3 确保头文件可访问:](#3 确保头文件可访问:)
在Linux中,库library是一组函数和资源的集合,他们可以被不同的程序共享和使用,库的主要目的是代码重用,减少内存占用,并简化程序的维护。
Linux操作系统支持的函数库分为:静态库和动态库。
静态库(Static Library)
- libxxx.a,通常以**.a为文件后缀,**
- 在编译时就将库编译进可执行程序中,每个使用该库的程序都会有一份库代码的副本。
- 优点:程序的运行环境中不需要外部的函数库。
- 缺点:可执行程序大,内存使用效率低,库更新需重新编译。
动态库(Dynamic Library)
-
又称共享库,通常以**.so(shared object)为文件后缀。**
-
在编译时,程序只记录了动态库的位置和所需的函数接口,而不是将库代码直接复制到可执行文件中。运行时,操作系统负责加载所需的库。
-
优点:可执行程序小,因为库代码不是直接包含在程序中。 库更新不需要重新编译,多个程序可以共享一份库代码,节省内存。
-
缺点:程序的运行环境中必须提供相应的库。增加程序的依赖性,动态链接可能会影响程序的启动速度(因为在运行时需要解析库)。还需要保证库的版本与程序兼容,否则会出错。
函数库目录:/lib /usr/lib
静态库与动态库的选择:
选择使用静态库还是动态库通常取决于具体的需求:
- 如果程序需要在没有网络连接的环境中运行,或者需要最小化可执行文件的大小,可能会选择静态库。
- 如果希望减少内存占用,或者需要频繁更新库而不重新编译程序,动态库可能是更好的选择。
静态库的制作与使用:
编写简单函数:
编写链接的源代码:
1.编写源代码为静态库:
通过命令 gcc sub.c -c -o sub.o
将源代码编译成目标文件(.o 文件),然后使用 ar 工具将这些目标文件打包成静态库。
ls - l 查看 sub.c 为源文件,sub.o为目标文件。
ar -cr -o libsub.a sub.o (静态函数库创建命令)
ar ‐cr libfile.a file.o
‐c: create的意思
‐r: replace的意思,表示当插入的模块file.o已经存在libfile.a中,则覆盖。反之ar显示一个错误消息。
libsub.a 创建成功:
2.编译程序时链接静态库:
gcc -o myprogram myprogram.c -L/path/to/library -lmylib
-L/path/to/library
指定静态库的搜索路径。-lmylib
指定要链接的库(编译器会自动寻找libmylib.a
文件)。
shell命令:
gcc main.c -L. -lsub
编译链接我们刚才写的代码文件。
执行中间文件:
./a.out
输出结果,证明我们链接成功。
3 确保头文件可访问:
如果静态库中的函数需要包含头文件,确保在编译程序时指定头文件的路径。
gcc -o myprogram myprogram.c -L/path/to/library -lmylib -I/path/to/header
-I/path/to/header
指定头文件的搜索路径。
操作静态库的几个实例:
情况1: 如果从别处得到一个静态库libunknown.a,想知道其中包含哪些模块。
命令:ar -t libunknown.a
静态库的编译:gcc -o main main.c -L. -lfile
- 编译main.c就会把静态函数库整合进main。
- 其中: -L指定静态函数库的位置供查找,注意L后面还有'.',表示静态函数库在本目录下查找。
- -l则指定了静态函数库名,由于静态函数库的命名方式是lib***.a,其中的lib和.a忽略。
删除libaddsub.a后main依然可以运行,因为静态库的内容已经整合进去了。
动态库的制作与使用:
1.编写源代码:
首先编写你的库函数的源代码。这里使用刚才静态库的代码。
命令:gcc sub.c -c -o sub.o 将源代码编译为目标文件,o。
2.编译源代码为位置无关代码,生成动态库:
gcc -fpic -shared -o libsub.so sub.o
‐fpic:产生位置无关代码。
‐shared:生成共享库。
-o output 缩写,输出为:
linsub.so的动态库。
sub.o
:这是要被链接成动态库的目标对象文件。用上述命令生成libaddsub.so 动态函数库。
生成libsub.so 动态库的可执行文件。
3.编译时链接动态库
方法一:
gcc main.c -o main -L. -lsub
此时还不能立即./out,因为在动态函数库使用时,会查找/usr/lib /lib目录下的动态函数库,而此时我们生成的库 不在里边。
第一种方法: libaddsub.so放到/usr/lib 或/lib中去。
sudo mv libsub.so /usr/lib
此时通过这条命令,我们已经将libsub.so 这个动态库文件移到/usr/lib里面去。
然后回到用户目录执行main,可以得知动态库链接成功。
记得将目录移回来:
方法二:
第二种方法,假设libfile.so在/home/linux/file 环境变量方法
export LD_LIBRARY_PATH=/home/linux/addsub:$LD_LIBRARY_PATH
终端关闭环境变量将会重置。
export
命令用于设置或导出环境变量,使得这些变量在当前 shell 会话中可用,并且可以在子进程中继承。
echo
命令在 Linux 和其他类 Unix 系统中用于在终端打印文本或变量的值。它常用于脚本中以输出信息或用于命令行中以显示数据。
执行main。链接成功。
方法三:
第三种方法: 在/etc/ld.so.conf文件里加入我们生成的库的目录,然后/sbin/ldconfig。
sudo vi /etc/ld.so.conf
/etc/ld.so.conf是非常重要的一个目录,里面存放的是链接器和加载器搜索共享库时要检查的目录,默认是 从/usr/lib /lib中读取的,所以想要顺利运行,可以把我们库的目录加入到这个文件中并执行/sbin/ldconfig。
/sbin/ldconfig
是 Linux 系统中用于配置动态链接器运行时绑定的命令。它主要负责创建、更新和删除动态链接库的缓存文件,以及检查动态链接库的版本信息和依赖关系。这个命令对于管理系统中的共享库非常重要,因为它确保了在运行时能够找到正确的动态链接库。
在此目录下,添加动态库目录的路径。
sudo ldconfig /etc/ld.so.conf
ldconfig
命令是 Linux 系统中用于配置动态链接器的命令。它主要用来创建和更新动态链接库的缓存,以便在程序运行时能够快速找到所需的库文件
ldconfig
命令会根据/etc/ld.so.conf
文件以及/etc/ld.so.conf.d/
目录下的所有.conf
文件中指定的路径来查找动态链接库,并更新缓存。
执行main。链接成功。