概述
linux下有两种库:动态库和静态库 二者的不同点在于代码被载入的时刻不同。
静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。
不同的应用程序如果调用相同的库,那么在内存中只需要有一份该动态库(共享库)的实例。
静态库和动态库的最大区别,静态情况下,把库直接加载到程序中,而动态库链接的时候,它只是保留接口,将动态库与程序代码独立,这样就可以提高代码的可复用度,和降低程序的耦合度。
静态库在程序编译时会被复制到目标代码中,程序运行时将不再需要该静态库。
动态库在程序编译时并不会被复制到目标代码中,而是在程序运行是才被载入,因此在程序运行时还需要动态库存在
-
静态库的编写和使用
命名规则:lib库名.a
-
将所有要加入静态库的模块编译为目标文件.
juggler@ubuntu:~/uc/day03/t_math$ ls add.c main.c mul.c p_math.h juggler@ubuntu:~/uc/day03/t_math$ gcc -c add.c mul.c tarena@ubuntu:~/uc/day03/t_math$ ls add.c add.o main.c mul.c mul.o p_math.h
-
将第一步生成的目标文件打包到静态库文件中
juggler@ubuntu:~/uc/day03/t_math$ ar -r libpmath.a *.o ar: 正在创建 libpmath.a juggler@ubuntu:~/uc/day03/t_math$ ls add.c libpmath.a mul.c p_math.h add.o main.c mul.o
-
使用静态库文件链接生成可执行文件
juggler@ubuntu:~/uc/day03/t_math$ gcc -c main.c juggler@ubuntu:~/uc/day03/t_math$ gcc main.o -L. -lpmath juggler@ubuntu:~/uc/day03/t_math$ ls add.c a.out main.c mul.c p_math.h add.o libpmath.a main.o mul.o juggler@ubuntu:~/uc/day03/t_math$ ./a.out 6+2=8 -L路径 链接器寻找库文件的路径 -l库名 指定要找的库的名字 -I 路径 预处理时寻找头文件的路径
-
-
在UNIX中,使用ar命令创建或者操作静态库
ar archivefile objfile archivefile:archivefile是静态库的名称 objfile:objfile是已.o为扩展名的中间目标文件名,可以多个并列 参数 意义 -r 将objfile文件插入静态库尾或者替换静态库中同名文件 -x 从静态库文件中抽取文件objfile -t 打印静态库的成员文件列表 -d 从静态库中删除文件objfile -s 重置静态库文件索引 -v 创建文件冗余信息 -c 创建静态库文件
- 动态链接
-
动态链接库的制作和使用
* 命名规则 lib库名.so
-
将要加入动态库的源文件编译为目标文件(与位置无关的目标文件)
t_math$ls add.c main.c mul.c p_math.h t_math$gcc -c -fPIC add.c mul.c t_math$ls add.c add.o main.c mul.c mul.o p_math.h -fPIC:生成与位置无关的目标文件
-
将第一步生成的目标文件打包到动态库文件中
t_math$gcc -shared -o libpmath.so *.o t_math$ls add.c libpmath.so mul.c p_math.h add.o main.c mul.o
-
使用动态库链接生成可执行文件
t_math$gcc main.c -L. -lpmath t_math$ls add.c a.out main.c mul.o add.o libpmath.so mul.c p_math.h t_math$a.out a.out: error while loading shared libraries: libpmath.so: cannot open shared object file: No such file or directory
-
使用静态库链接生成的可执行文件.从静态库中找到程序中使用的模块,将这些模块合并到可执行文件中.可执行文件是独立的文件.不再依赖静态库文件.
-
使用动态库生成的可执行文件.和动态库是两个独立的模块.这种可执行文件要执行的时候,必须将可执行文件和动态库一起加载到内存.
-
需要指到可执行文件依赖哪些动态库文件?
ldd a.out -
告诉动态链接器到哪里去找动态库文件.
两种方法解决-
使用LD_LIBRARY_PATH环境变量告诉动态链接器
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
-
链接器默认的搜索路径是/lib或者/usr/lib
mv libpmath.so /lib mv libpmath.so /usr/lib
-
-