首先简单了解一下什么是库?
预先编译好的集合就是库。
根据连接时期不同,库分为静态库和共享库。静态库是在程序编译时期链接的,动态库是在程序运行时期链接的。
linux上库的命名一般为:libxxx.a(静态库)libxxx.so动态库,库文件存放的地点位/lib或者/usr/lib
一、静态库
1、命名规则
lib + 库名 + .a //注:静态库的后缀是: .a
如: libMySql.a , 其中MySql是库名
2、制作静态库的步骤
(1)生成对应的 .o 文件 ------ -c ------> .o (使用gcc的 -c 选项)
注:生成的 .o 与位置有关
(2)将生成的 .o 文件打包
在打包时需用到 ar 工具
ar rcs + (静态库的名字) + 所有生成的 .o
3、发布和使用静态库
(1)发布静态库
一般仅提供给使用者 include目录 和 lib目录
(2)头文件:程序的功能接口声明全在 .h 文件中,所以需提供给用户方便使用
(3)简单查看库内信息,需使用nm
nm libMyTest.a
4、使用静态库的优缺点
优点:
1、发布库的时候,不需要提供对应的库
//在主函数中使用时,仅仅是打包传送所需的 .o 文件,静态库文件传输以 .o 为单元
2、静态库被打包到应用程序中,加载速度相对较快
缺点:
1、库被打包到应用程序中,导致库的体积很大
2、库一旦发生改变,需要重新编译程序
5、静态库打包工具——ar
常用参数
格式:ar rcs libxxx.a xx1.o xx2.o
注:
libxxx.a是你需要生成的静态库;
xx1.o xx2.o 是需要打包依赖的.o文件;注意可以是.a文件(例如ar rcs libxxx.a xx1.o xx2.a)
r:在库中插入模块(替换)。当插入的模块名已经在库中存在,则替换同名的模块。
如果若干模块中有一个模块在库中不存在,ar显示一个错误消息,并不替换其他同名模块。
默认的情况下,新的成员增加在库的结尾处,可以使用其他任选项来改变增加的位置。
c:创建一个库。不管库是否存在,都将创建。
s:创建目标文件索引,这在创建较大的库时能加快时间。
(补充:如果不需要创建索引,可改成大写S参数;如果.a文件缺少索引,可以使用ranlib命令添加)
二、共享库(动态库) ------》 windows 下的 .dll 文件
注:程序加载起来后才去加载动态库,不会被打包到应用程序中
1、命名规则
//linux
lib + 库名 + .so
//windows
lib + 库名 + .dll
2、制作步骤
(1)生成与位置无关的代码(生成与位置无关的 .o)
gcc -fPIC -c *.c
// -fPIC 生成与位置无关的 .o 文件
(2)将 .o 打包成动态库
共享库打包仍使用gcc
gcc -shared -o libMyTest.so *.o -I../include
3、动态库连接不成功解决方案
(1): 把生成的动态库拷贝到/lib目录下(最好别用,用了就挨批)
cp libMyTest /lib/.
(2): 临时测试时用(测试,使用一个临时的环境变量)
系统有一个环境变量 LD_LIBRARY_PATH,此环境变量内部的路径,在加载动态库
时,链接器会优于默认路径查找库(此方法时临时生效)
export LD_LIBRARY_PATH=./lib
注: export 导出环境变量
(3)实现永久的动态库环境配置
配置到bash的配置文件中
vim .bashrc (在配置文件中,最后加入一行)
export LD_LIBRARY_PATH=/home/lh/libtest/lib (此处必须是绝对路径)
source .bashrc 生效配置
(4)必须掌握:(工作常用)
1、找到动态链接器的配置文件----》把自己动态库的路径写入文件
注: /etc/ld.so.conf链接器配置文件
2、更新配置文件 sudo ldconfig -v (-v 显示更新过程中的内容)
4、查看可执行程序的依赖项
ldd 查看可执行程序需要依赖的所有的动态库
如 : ldd myapp
5、共享库须知
libc.so.6 Linux下标准的C库
/lib64/ld-linux-x86-64.so.2 Linux下标准的动态链接器,其实就是一个动态库
在程序运行时用于加载动态库
6、动态库的优缺点
注:动态库不会被加载到应用程序中
优点:
1、执行程序体积小
2、动态库的更新操作比较方便,一般不需要重新编译程序
缺点:
1、发布程序的时候,需要将动态库提供提供给用户
2、动态库没有被打包到应用程序中,加下速度会相对较慢
三、两者简单小结
链接静态库其实从某种意义上来讲也是一种粘贴复制,只不过它的操作对象是目标代码而不是源代码。
因为静态库被链接后库就直接嵌入可执行文件中了,这样就会浪费系统空间。如果多个程序链接了同一个
库,则每生成一个可执行文件就会有一个库的副本,必然会浪费系统空间。
而动态库的出现就弥补了静态库上的弊端,因为动态库是在程序运行时被链接的,所以磁盘上只保留
一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。
因为动态库在程序运行时被链接,所以程序的运行速度会比链接静态库的版本慢。当然,和动态科库的优点
比起来缺点就微不足道了。