【发布时间】:2013-12-21 17:57:09
【问题描述】:
在编译 C/C++ 程序时,有没有办法在不使用 ld 嵌入版本信息的情况下链接到 Linux 中的库导出?
我正在构建一个链接到 Firefox 中的 libxul.so 的共享对象(它是一个 Firefox 二进制扩展)。我想构建我的共享对象并链接到 libxul.so,以便在运行时,加载程序不关心 libxul.so 是什么版本。
现在,我的输出 .so 文件具有以下依赖项:
readelf -V myext.so
0x0080: Version: 1 File: libxul.so Cnt: 1
0x0090: Name: xul24.0 Flags: none Version: 9
(注意它取决于版本'xul24.0')
导出的函数在 Firefox 版本之间不会改变。所以,我想删除这个版本说明。
尝试加载到 Firefox 26 时,LD_DEBUG=file 提供以下错误:
/usr/lib/firefox/libxul.so: error: version lookup error:
version `xul24.0' not found (required by /.../myext.so) (fatal)
对于 Firefox 26 版本的 libxul.so,版本为'xul26'。
那么,如何防止 ld 将版本信息嵌入到我的库中?
【问题讨论】:
-
当您链接到 libxul24 然后尝试针对 libxul26 运行时,某些函数的 API 和/或 ABI 会发生变化,这就是您不允许这样做的原因。这是一个完整性检查:您想从一个库中使用的函数在另一个库中不一定相同(xul26 本质上就是这样)。
-
@mirabilos 即使没有任何更改,构建工具也有可能自动分配版本号。这是事实库版本与整个产品版本相同的提示。此外,对于一些工具,例如 gettext,我也看到了这一点,其中库版本和功能更改之间没有关联。但是一旦不能保证 API 不会改变,仍然不能依赖安全加载其他库版本...
-
@Netch:当然,但他不是生成 XUL 库的人。在这种情况下,我相信它是一个产品内部库,上游甚至不假装关心 API/ABI 稳定性(不知道是否应该首先链接它)。所以我认为这是 M*zilla 人的故意。
-
Mozilla 强制执行的其他版本兼容性检查(即扩展包中的 minVersion 和 maxVersion 设置),比链接版本号更细粒度和灵活。无论如何,这对 Linux 来说是个大问题,因为相同的代码在 Windows 和 Mac 中运行良好。我们使用 dlopen() 并动态链接到所有 libxul 导出的解决方法将比值得的成本更高。
-
@mirabilos 是的,我已经看到了。尽管如此,我认为即使改变 ABI 也可以附加一个外国图书馆对学术目的有用 - 合适的玩具应该是易碎的,否则它们不会教:)