动态库静态库辨析
首先在这里放一个知乎的文章链接
静态库与动态库的编译与链接
- 静态库 .a 的链接是“假链接”,只是单纯的把所有的.o文件进行了一个打包,没有对任何符号进行处理
- 动态库 .so 的链接是“真链接”,对输入的.op文件进行了相应的符号处理(相似段合并)
但是要注意的一点是,动态库在编译完成后,如果提供给其他程序使用,必然是动态装载的; 而静态库编译完成给其他程序使用时,是在编译阶段就链接进去并进行了处理。
也就是说,如果编译成了动态库,其他的.o文件不能使用该动态库中的任何符号;而如果是静态库,则可以使用静态库中的符号,原因就是在与静态库会参与链接,而动态库只能是装载。
理解这一点,对接下来的实例理解有帮助。
静态库链接实例
我之所以想到研究这个问题,最主要的原因是在于修改 jiajia 这个项目时,遇到的问题
目前jiajia静态库与app链接的步骤:
jiajia.src -> jiajia.src.o -> libjia.a,使用ar静态链接libjia.a && app.o && ibverbs.so -> app,注意到这一步还是DNF文件,因为-libverbs只是指定了需要链接的动态库,还需要进行动态装载,不是一个单纯的可执行ELF文件
我想进行的两个修改:
(jiajia.src -> jiajia.src.o) && ibverbs -> libjia.a
在生成libjia.a库时,直接将ibverbs动态库包含进来,因此用户程序在进行编译时,不需要额外地去指定-libverbs,可以直接用libjia.a中的动态库
结论: 这种方法不可行,因为libjia.a静态库在编译的时候就表示这个库只能是由一些.o文件组成的,不能允许其中有动态库的存在
``(jiajia.src -> jiajia.src.o) && ibverbs -> libjia.so`
在生成libjia.so库时,直接将ibverbs动态库包含进来。与上述的libjia.a不同,希望.so可以包含进其他的动态库
结论: 在生成动态库时可行,但是在与app.o链接时出现问题。这里的问题就是上述所说的 动态库.so必须是动态装载 ,因此其中提供的符号不会在链接时提供给app.o,所以就会出现app.o在链接时出现符号找不到的情况
思考
我目前的看法是,
- 动态库本身应该看作一个独立的单元,也就说与其动态链接的文件不应该使用其中的任何符号,因为动态库提供的这些符号不会参与链接;
- 静态库则相反,由于其中提供的符号会参与真正的链接,所以如果遇到在编写某个C文件需要用到某个库中的符号时,这个库一般来讲都得是静态库。
Leave a comment