当我使用的库所使用的库改变时,我的可执行文件是否需要重新链接?
问题描述:
假设我们有一个可执行的EXE 依赖于共享库富,而这又取决于共享库酒吧上:EXE需要libfoo.so和富需求libbar.so。 然后,条以源兼容方式(即,API不变)而不是二进制兼容方式(即ABI改变)改变。因此,我们必须重新链接(或面对分段错误)。当我使用的库所使用的库改变时,我的可执行文件是否需要重新链接?
现在的问题是:究竟应该重新编译/重新链接?
让我来说明一点。要链接EXE,我们不需要添加编译器选项 “-lbar”,而我们确实需要该选项用于连接富:
gcc -fPIC -shared -I. -Ibar -lbar -o libfoo.so foo.o
gcc -fPIC -I. -Ifoo -Ibar -lfoo -o exe exe.o
因此,是否足以重新链接FOO ,并离开exe是?
做富和EXE还需要重新编译(如果酒吧改变,但其API是不变的)?
最后,我试图离开富不变,但重新链接EXE与添加的 “-lbar” 编译器选项:
gcc -fPIC -I. -Ifoo -Ibar -lfoo -lbar -o exe exe.o
这的确消除了分段错误,这可能意味着那么所有东西都可以正确链接......或者可以通过剪切运气(因为即使存在继承内存问题,也不总是发生分段错误)。
开始=>
答
直到专家的答案,这些都是我自己的假设:
鉴于链接器不需要“-lbar”exe,我倾向于得出结论exe不需要重新链接,因为链接器显然不需要bar。不过,我对此很不确定,因为这里假设连接器没有找到bar via foo。 (毕竟,
ldd libfoo.so
会告诉我酒吧,所以我想说的是,接头可拥有的知识,它需要酒吧)不,他们没有。源代码是兼容的,所以编译后的(对象)文件中的符号仍然是正确的/兼容的。然而,可执行文件需要重新链接,因为这些符号在目标文件中的位置已经改变。
看起来这是允许的......但我不确定。另外:任何取决于foo以外的任何可执行文件/ exe仍将面临分段错误,所以这将是不好的做法,不是吗?
这是一种咕噜的工作,你应该总是留给一台机器弄清楚。不是因为它很难做到,而是因为它很乏味,当你没有足够注意时,你会失去一个小时的生活。在那里有许多构建系统,选择一个。 –
@HansPassant我正在使用构建系统,[wmake](https://cfd.direct/openfoam/user-guide/compiling-applications/),这是开源的计算流体动力学软件OpenFoam的自定义。要问的原因是OpenFoam包含许多不同的可执行文件(“解决者”),它们依赖于许多动态库来完成这项工作。为了达到我的目的,我调整了一个这样的库(_bar_),并且我认为通过简单地覆盖现有的动态库,所有求解器都可以工作:但是他们给了我段错误。这就是为什么我要问什么应该重新链接。 –