简体   繁体   English

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

[英]Linking multiple incompatible versions of a static library into one executable

I am presently developing for a system which discourages (ie essentially forbids) dynamic libraries. 我目前正在开发一个不鼓励(即基本上禁止)动态库的系统。 Therefore, everything has to be linked statically. 因此,一切都必须静态链接。

The application framework I am using (which cannot be changed) is using an old, statically-linked version of a library libfoo.a (version r7). 我正在使用的应用程序框架(无法更改)使用库libfoo.a (版本r7)的旧的静态链接版本。 A library I am using, libbar , needs libfoo.a version r8 (specifically, some of the new features are crucial for the library to function). 我正在使用的库libbar需要libfoo.a版本r8(具体来说,一些新功能对于库的运行至关重要)。 I can edit and recompile libbar as well as libfoo r8, but I want to avoid changing them as much as possible because I am not very familiar with the code (and would have to pass code changes upstream). 我可以编辑和重新编译libbar以及libfoo r8,但我想避免尽可能多地更改它们,因为我不熟悉代码(并且必须在上游传递代码更改)。

Unfortunately, the two libfoo libraries have a substantial number of symbols in common. 不幸的是,这两个libfoo库有很多共同的符号。 So, the linker spits out a ton of "multiple symbol definition" errors. 因此,链接器会吐出大量的“多符号定义”错误。

I've heard it's possible to use objcopy and friends to "inline" a static library into another. 我听说可以使用objcopy和朋友将静态库“内联”到另一个库中。 However, I'm not really sure how to achieve this in practice, nor if it's even the best option. 但是,我不确定如何在实践中实现这一点,也不是最好的选择。

So, how can I successfully compile an executable which uses two, incompatible versions of the same library? 那么,如何成功编译使用同一个库的两个不兼容版本的可执行文件? I've already considered avoiding this situation but it will be much harder to work with. 我已经考虑过要避免这种情况,但要与它合作会更加困难。

It turns out that this is actually possible with some ld and objcopy magic. 事实证明,这实际上可能是一些ldobjcopy魔术。

Basically, the procedure looks like this: 基本上,程序看起来像这样:

# 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

This effectively creates a single super-library which exports only the symbols from the original libbar , and which has the other library relocated in. 这有效地创建了一个单独的超级库,该库只导出原始libbar的符号,并且其他库重新定位。

There's probably another, cleaner way to achieve this result, but this method works for me and allows me to statically link two incompatible libraries into the same executable, with no apparent ill effects. 可能有另一种更清晰的方法来实现这个结果,但是这个方法对我有用,并且允许我将两个不兼容的库静态链接到同一个可执行文件中,没有明显的不良影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM