编译 C/C++ 程序时,有没有一种方法可以链接到 Linux 中的库导出,而无需 ld 嵌入版本信息?
我正在构建一个链接到 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
Run Code Online (Sandbox Code Playgroud)
(请注意,这取决于版本“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)
Run Code Online (Sandbox Code Playgroud)
对于 Firefox 26 版本的 libxul.so,版本为'xul26'
.
那么,如何防止 ld 将版本信息嵌入到我的库中呢?
我能够根据需要构建库,而无需版本信息。
\n\n我最终做的是使用适当的导出符号创建一个虚拟库——没有版本(或soname)信息——并在编译和链接我的库时链接到该虚拟库。在运行时,加载器加载真实库(libxul.so),不会因版本控制问题而失败,因为我的库不包含真实库的版本信息。为了弄清楚我需要哪些导出的符号,我首先链接到真实的 libxul.so,然后用于readelf --dyn-syms
确定实际需要哪些符号。
其中 ARCH 为 32 或 64(对于 32 位或 64 位编译):\ngcc -o $ARCH/libxul.so -fPIC -shared -DM$ARCH -m$ARCH xulstubs.c
xulstubs.c:
\n\n/*\n 2: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_Realloc@xul26 (2)\n 3: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_UTF16ToCString@xul26 (2)\n 7: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_CStringCloneData@xul26 (2)\n13: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_GetMemoryManager@xul26 (2)\n...\n */\nvoid NS_Realloc() {}\nvoid NS_UTF16ToCString() {}\nvoid NS_CStringCloneData() {}\nvoid NS_GetMemoryManager() {}\n/* ... etc. ... */\n
Run Code Online (Sandbox Code Playgroud)\n\n现在,从我的库导入的符号没有版本附加:
\n\n23: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_Realloc\n29: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_UTF16ToCString\n33: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_CStringCloneData\n37: 0000000000000000 0 FUNC GLOBAL DEFAULT UND NS_GetMemoryManager\n
Run Code Online (Sandbox Code Playgroud)\n\n它按预期运行。
\n\n我仍然想要一个更 \xe2\x80\x9celegant\xe2\x80\x9d 解决方案,一个不需要创建虚拟库的解决方案。但是,如果这是使用标准工具链的唯一解决方法,我可以接受。
\n 归档时间: |
|
查看次数: |
3200 次 |
最近记录: |