linux下的静态库依赖
背景
linux的静态库.a
和动态库.so
的区别很大,静态库基本上只是一系列.o
文件的集合加上符号表,没有链接过程,不能依赖链接其他的静态库或者动态库。如果静态库中用到了其他的库,需要这个静态库的使用者在最终的链接阶段清楚所有使用到的库,然后一一链接。
如果静态库依赖的库很多的话,而且依赖的关系很复杂,那么对于最终的使用者来说绝对是一场噩梦。
方案
linux下的静态库其实就是一系列.o
文件的集合加上符号表。那么如果把它所依赖的静态库里的.o
全部提取出来,然后再一起打包,更新符号表,是不是最终的使用者就可以不用管这些依赖了呢?
答案是的确可以,优点就是使用者不用去关心一堆静态库依赖,缺点是静态库的编写者需要花费更多的精力,并且静态库的体积会增大。
那么静态库依赖的动态库怎么办呢?
没有办法,静态库上没有链接信息,也不可能把动态库包含在里面,所以静态库如果真的依赖其他库,最好都依赖静态库。
打包
那么怎样将一个静态库打包到另一个静态库里呢?
静态库打包工具ar
提供了-q
选项来追加.o
文件,理论上把所有依赖的静态库解开后打包是可行的,但是这样很难使用脚本来自动化打包,接下来我们使用一种很少见的方式来直接将.a
添加到另一个.a
中。
ar
有一个选项-M
,可以执行一种ar
脚本,这种脚本的资料非常少,在man ar
中都没有介绍。我们接下来就使用这种脚本来将一个静态库添加到另一个静态库中。
CREATE libstatic.a
SAVE
END
这个脚本的作用是创建一个空的名为libstatic.a
的库,以上脚本保存为ar.mac
执行ar -M < ar.mac
,可以看到这里是使用了重定向输入来执行脚本的。
ar -q libstatic.a s1.o
ar -q libstatic.a s2.o
ar -q libstatic.a s3.o
然后在shell中执行上面的命令,将静态库自己的.o
文件添加到库中。
OPEN libstatic.a
ADDLIB libstatic123.a
SAVE
END
这个脚本的作用是打开库文件然后添加另一个依赖库文件。
将脚本保存后同样使用ar -M
执行。
这样就完成了将一个库添加到另一个库中,此时可以使用ar -t
命令查看一下库里面的内容,可以看到依赖库的.o
文件都被包含进去了。