想象一下,我们有一个依赖于共享库 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
因此,重新链接 foo 并保留 exe 就足够了吗?
foo 和 exe 还需要重新编译(如果 bar 已更改,但其API未更改)?
最后,我尝试保持 foo 不变,但使用添加的“-lbar”编译器选项重新链接 exe :
gcc -fPIC -I. -Ifoo -Ibar -lfoo -lbar -o exe exe.o
这确实消除了分段错误,这可能意味着所有内容都正确链接......或者它可以通过剪切运气(因为即使存在继承,分段错误也不会总是发生记忆问题)。
答案 0 :(得分:0)
在专家回答之前,这些是我自己的假设:
鉴于链接器不需要&#34; -lbar&#34;对于 exe ,我倾向于得出结论 exe 不需要重新链接,因为链接器显然不需要 bar 。但是,我对此非常不确定,因为这假设链接器没有通过 foo 找到 bar 。 (毕竟,ldd libfoo.so
会向我显示 bar ,所以我说链接器可能拥有它需要的知识 bar 。)
不,他们没有。源是兼容的,因此编译(对象)文件中的符号仍应正确/兼容。但是,可执行文件需要重新链接,因为目标文件中这些符号的位置已经改变。
看来这是允许的......但我不确定。另外:任何依赖于 foo 而不是 exe 的可执行文件/库仍然会面临分段错误,所以这不好做,不是吗?
< / LI> 醇>