将多个不兼容的静态库版本链接到一个可执行文件中

时间:2014-03-04 23:52:05

标签: c static-libraries

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

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

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

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

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

1 个答案:

答案 0 :(得分:2)

事实证明,实际上这可能会带来一些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中的符号,并重新定位了另一个库。

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