动静态库概述
静态库(.a)文件:程序在编译链接的时候把库的代码直接链接到可执行文件中,程序运行的时候就不再需要静态库
动态库(*.so)文件:程序在运行的时候才会链接库的代码。
因此,一个动态库的可执行文件,只需要知道我需要去哪里找哪个函数就好。所以在链接动态库的可执行文件只需要包含一个需要用的函数入口地址的表,在执行的时候再去链接就好。
而链接静态库的可执行文件则在编译链接时,将外部函数所在目标文件的整个机器码放进来。
所以通过链接静态库生成的可执行文件会比通过链接动态库生成的可执行文件大很多。因为需要保存更多的代码。但是通过链接静态库的可执行文件可以直接更简单的移植。而链接动态库的可执行文件需要一直依赖动态库才能运行。也因此动态库链接的可执行文件也就会更小。
同时,动态库只需要一份,就可以给所有的程序使用,会节省大量的磁盘空间。例如:当我们有十个文件用到了同一个库下的一个函数时,如果使用的是静态库。那么这个函数的机器码就会被重复拷贝出十份。而通过动态库链接的可执行程序就不会。 操作系统通过虚拟内存映射,允许物理内存中的一份动态库可以在用到的所有进程中共享。
生成静态库
我们可以通过创建相应的.h文件和.c文件,然后通过通过“ar -rc”命令生成对应的静态库文件,“ar -tv”命令可以查看静态库下的目录列表。
生成动态库
生成动态库的方法与生成静态库类似。
但是需要注意的是,生成动态库,需要格外增加FPIC 产生位置无关码 ;
“shared”表示生成共享库格式。
使用自己的库
需要注意, 当我们要使用自己生成的库时,需要在makefile相应的位置增加 -L -I选项。
-L 链接库所在的路径。
-I 链接动态库的名字, (一般库的名称会有三部分 lib + 名称+ 版本号) 这里需要我们去掉前面的lib 和.so后缀即版本号, 即只需要保留“lib”后的,“.so"前即可。
同时,我们运行动态库时,需要
- 将.so文件文件复制到系统共享库的路径中,一般情况下在 /usr/lib 中,但是这种方法会污染我们的系统库。
- 我们还可以更改LD_LIBRARY_PATH, 我们可以自己创建一个目录文件,将我们自定义需要用到的外部库全部放在这个目录文件中,然后添加这个目录到LD_LIBRARY_PATH就好了。