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

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

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

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

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

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

最佳答案 事实证明,这实际上可能是一些ld和objcopy魔术.

基本上,程序看起来像这样:

# 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中的符号,并且其他库重新定位.

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

点赞