静态库
把多个.o文件打包成静态库,以libXXX.a的格式命名,程序链接时,会把静态库集成在可执行文件中,程序运行时,会直接加载到内存中。
生成静态库
- 静态库中添加或替换.o文件
ar r libXXX.a x1.o x2.o x3.o
注:如果.o文件不存在,就添加文件,如果.o文件已存在,就替换文件。 - 静态库中删除.o文件
ar d libXXX.a x1.o
- 查看静态库
ar tv libXXX.a
- 提取静态库中的.o文件
ar x libXXX.a x1.o
使用静态库
方法1:直接使用
gcc a.c libXXX.a
方法2:链接使用
gcc a.c -L静态库文件所在目录 -l静态库名
注意:libXXX.a的静态库名为XXX
共享库
把多个.o文件打包成共享库,以libXXX.so的格式命名,程序链接时,不会把共享库集成在可执行文件中,程序运行时,如果调用共享库中的函数,此时会把共享库加载到内存。
生成共享库
- 生成与位置无关的.o文件
gcc -c -fPIC a.c -o a.o
注意:共享库必须使用与位置无关的.o文件 - 打包共享库
gcc -shared a.o b.o c.o -o libXXX.so
- 查看.o文件是否使用-fPIC选项编译
nm a.o | grep _GLOBAL_OFFSET_TABLE_
有_GLOBAL_OFFSET_TABLE_,则表示使用了-fPIC选项
使用共享库
动态链接
因可执行文件不包含共享库,所以需要某种机制找出共享库所在路径通知动态链接器
方法1:环境变量:LD_LIBRARY_PATH
方法2:配置文件:/etc/ld.so.conf
方法3:编译时指定:gcc -Wl,rpath,/共享库目录
直接使用
gcc a.c libXXX.so
链接使用
gcc a.c -L共享库目录 -l共享库名
带有so-name的共享库
生成有so-name的共享库
gcc -shared -Wl,-soname,libBBB.so -o libAAA.so a.o b.o c.o
-Wl,-soname,libBBB.so:指定共享库AAA的so-name为BBB生成软链接文件
ln -s libAAA.so libBBB.so
共享库的版本控制
真实名称
libXXX.so.1.0.1
第一个数字:大版本号
后两个数字:修订号真实名称、so-name、链接名称三者的关系
真实名称:libXXX.so.1.0.1,共享库实际的文件
so-name:libXXX.so.1,区分大版本,不同大版本之间不兼容
链接名称:libXXX.so,链接时使用,此名称一直不变使用标准规范创建一个共享库
gcc -g -c -fPIC mod1.c mod2.c mod3.c
gcc -g -shared -Wl,soname,libdemo.so.1 -o libdemo.so.1.0.1 mod1.o mod2.o mod3.o
ln -s libdemo.so.1.0.1 libdemo.so.1
ln -s libdemo.so.1 libdemo.so
安装共享库
cp libXXX.so.1.0.1 /指定目录
ln -s libXXX.so.1.0.1 /指定目录/libXXX.so.1
ln -s libXXX.so.1 /指定目录/libXXX.so
共享库安装路径
/lib
/usr/lib
/usr/local/lib
共享库升级小版本
编译好小版本后,放入指定路径
运行ldconfig -v
可以自动更新小版本共享库升级大版本
拷贝libXXX.so.2.0.0放入指定路径
执行ldconfig -v
更新,会生成libXXX.so.2软链接
执行ln -s libXXX.so.2 libXXX.so
混合链接静态库、共享库
当静态库和共享库同名时,编译器默认会优先使用共享库,如果共享库不存在,则使用静态库。
- 全部使用静态库
gcc a.c -static -L库目录 -lXXX
- 混合使用静态库、共享库
gcc a.c -L库目录 -Wl,-dn -lX1 -Wl,-dy -lX2
-Wl,-dn:表示开始使用静态库
-Wl,-dy:表示结束使用静态库
注意:-Wl,-dn 和 -Wl,-dy要成对出现