【问题标题】:Linking multiple incompatible versions of a static library into one executable将静态库的多个不兼容版本链接到一个可执行文件中
【发布时间】:2014-03-04 23:52:04
【问题描述】:

我目前正在开发一个不鼓励(即基本上禁止)动态库的系统。因此,一切都必须静态链接。

我正在使用的应用程序框架(无法更改)正在使用旧的静态链接版本的库 libfoo.a(版本 r7)。我正在使用的库 libbar 需要 libfoo.a 版本 r8(具体来说,一些新功能对于库的运行至关重要)。我可以编辑和重新编译libbarlibfoo r8,但我想尽可能避免更改它们,因为我对代码不是很熟悉(并且必须在上游传递代码更改)。

不幸的是,这两个libfoo 库有大量共同的符号。因此,链接器会吐出大量“多符号定义”错误。

我听说可以使用objcopy 和朋友将静态库“内联”到另一个库中。但是,我不确定如何在实践中实现这一点,也不确定它是否是最佳选择。

那么,我如何才能成功编译使用同一库的两个不兼容版本的可执行文件?我已经考虑过避免这种情况,但这样会更难处理。

【问题讨论】:

  • 嗯,objcopy --localize-symbol 看起来很有希望。也许您可以先将旧库和需要它的对象归档,然后隐藏所有现在内部的符号?
  • 我可以确认我已使用 objcopy 重命名库中的符号以处理不同库中使用的重复符号,例如libx 和 liby 都与 libz 链接,现在我想同时链接 libx 和 liby,所以 libz 符号出现两次。我通过重命名每个 libc 符号解决了这个问题,这样他们每个人都愉快地使用自己的符号名称前缀调用自己的版本。我还找不到脚本,但如果我找到了,我会告诉你的。

标签: c static-libraries


【解决方案1】:

事实证明,这实际上可以通过一些 ldobjcopy 魔法来实现。

基本上,过程如下所示:

# Unpack libraries
ar x libbar.a
ar x libfoo.a
# Grab symbol table (symbols to export)
nm -Ag libbar.a | grep -v ' U ' | cut -d' ' -f 3 > libbar.sym
# Build a single object file with libfoo relocated in
ld -Er *.o -o libbar-merged.lo
# Localize all symbols except for libbar's symbols
objcopy --keep-global-symbols libbar.sym libbar-merged.lo libbar-merged.o
# Create an archive to hold the merged library
ar crs libbar-merged.a libbar-merged.o

这有效地创建了一个超级库,它仅导出原始 libbar 中的符号,并且将另一个库重新定位到其中。

可能还有另一种更简洁的方法来实现此结果,但这种方法对我有用,并且允许我将两个不兼容的库静态链接到同一个可执行文件中,而没有明显的不良影响。

【讨论】:

  • 顺便说一句,nm 命令有点讨厌。所以,如果有更好的方法来获取库中所有已定义的全局符号列表,我会全力以赴。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多