当我使用的库使用的库发生更改时,我的可执行文件是否需要重新链接?

时间:2017-06-21 13:49:22

标签: c++ gcc linker dynamic-library

想象一下,我们有一个依赖于共享库 foo 的可执行文件 exe ,而后者依赖于共享库 bar < em> exe 需要 libfoo.so foo 需要 libbar.so 。 然后, bar 以源兼容的方式(即API未改变)改变,但不以二进制兼容的方式改变(即ABI改变)。因此,我们必须重新链接(或面对分段错误)。

问题是:究竟应该重新编译/重新链接的内容?

让我更具体一点。要链接 exe ,我们不需要添加编译器选项“-lbar”,而我们确实需要用于链接 foo 的选项:

gcc -fPIC -shared -I. -Ibar -lbar -o libfoo.so foo.o
gcc -fPIC -I. -Ifoo -Ibar -lfoo -o exe exe.o
  1. 因此,重新链接 foo 并保留 exe 就足够了吗?

  2. foo exe 还需要重新编译(如果 bar 已更改,但其API未更改)?

  3. 最后,我尝试保持 foo 不变,但使用添加的“-lbar”编译器选项重新链接 exe

    gcc -fPIC -I. -Ifoo -Ibar -lfoo -lbar -o exe exe.o
    

    这确实消除了分段错误,这可能意味着所有内容都正确链接......或者它可以通过剪切运气(因为即使存在继承,分段错误也不会总是发生记忆问题)。

    1. 是否允许这样做,即保持 foo 不变,但明确地将 exe bar 联系起来?
    2. 有些相关的读物:[1] [2] [3] [4] [5]

1 个答案:

答案 0 :(得分:0)

在专家回答之前,这些是我自己的假设:

  1. 鉴于链接器不需要&#34; -lbar&#34;对于 exe ,我倾向于得出结论 exe 不需要重新链接,因为链接器显然不需要 bar 。但是,我对此非常不确定,因为这假设链接器没有通过 foo 找到 bar 。 (毕竟,ldd libfoo.so会向我显示 bar ,所以我说链接器可能拥有它需要的知识 bar 。)

  2. 不,他们没有。源是兼容的,因此编译(对象)文件中的符号仍应正确/兼容。但是,可执行文件需要重新链接,因为目标文件中这些符号的位置已经改变。

  3. 看来这是允许的......但我不确定。另外:任何依赖于 foo 而不是 exe 的可执行文件/库仍然会面临分段错误,所以这不好做,不是吗?

    < / LI>