less than 1 minute read

首先在这里放一个知乎的文章链接


静态库与动态库的编译与链接

  • 静态库 .a 的链接是“假链接”,只是单纯的把所有的.o文件进行了一个打包,没有对任何符号进行处理
  • 动态库 .so 的链接是“真链接”,对输入的.op文件进行了相应的符号处理(相似段合并)

但是要注意的一点是,动态库在编译完成后,如果提供给其他程序使用,必然是动态装载的; 而静态库编译完成给其他程序使用时,是在编译阶段就链接进去并进行了处理。

也就是说,如果编译成了动态库,其他的.o文件不能使用该动态库中的任何符号;而如果是静态库,则可以使用静态库中的符号,原因就是在与静态库会参与链接,而动态库只能是装载。

理解这一点,对接下来的实例理解有帮助。

静态库链接实例

我之所以想到研究这个问题,最主要的原因是在于修改 jiajia 这个项目时,遇到的问题

目前jiajia静态库与app链接的步骤:

  1. jiajia.src -> jiajia.src.o -> libjia.a,使用ar静态链接
  2. 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文件需要用到某个库中的符号时,这个库一般来讲都得是静态库。

目前的思考还是非常不完备的,这篇文章也只是一个暂时性的总结。如果以后遇到了其他链接编译方面的问题,也回家到这篇文章中

Updated:

Leave a comment