【问题标题】:How to embed a static library into a shared library?如何将静态库嵌入到共享库中?
【发布时间】:2019-05-20 15:04:36
【问题描述】:

在 linux 上,我正在尝试创建一个共享库 libbar.so,它嵌入了一个商业静态库(许可很好)。商业库有 4 个版本:libfoo-seq.a、libfoo-mt.a、libfoo-seq.so 和 libfoo-mt.so(它们都提供相同的符号,只是代码是顺序/多线程的,并且该库是静态/共享的)。在这四个中,我希望我的代码始终使用顺序 foo 库,所以当我创建 libbar.so 时,我将我的目标文件和 libfoo-seq.a 链接在一起。

问题是我的库的用户在他们拉入我的 libbar.so 时可能已经拉入了 libfoo-mt.so,因此在读入 libbar.so 时来自 libfoo 的所有符号都已经存在,所以我对 foo 中函数的调用被解析为多线程版本。

我想知道如何解决这个问题?当我编译创建目标文件以及将目标文件与 libfoo-seq.a 链接以创建 libbar.so 时,我需要使用什么样的魔法标志?

【问题讨论】:

    标签: linux linker static-linking dynamic-linking undefined-symbol


    【解决方案1】:

    您可以通过版本脚本在 libbar 中隐藏 libfoo 的符号:

    $ cat libbar.map
    {
      global: libbar_*;
      local: libfoo_*;
    };
    $ gcc ... -o libbar.so -Wl,--version-script=libbar.map
    

    【讨论】:

    • 我的理解是,这样嵌入到我的 libbar.so 中的 libfoo 的功能将不会在外部可见。但这只是等式的一方面。我还需要如果 libfoo 的功能已经通过打开 libfoo-mt.so 被拉入,那么当它打开时它们不会“渗入”到 libbar.so 中,并且 libbar.so 仍然会使用来自 libfoo-序列号那部分也是真的吗?
    • 是的,如果 libfoo 的符号被隐藏(通过上面的脚本),您的库将不再尝试从外部导入它们(因此它们不会被覆盖)。您可以通过readelf -hS --dyn-syms 验证 libfoo 的二进制接口。
    • 听起来不错,我今天晚些时候试试。同时...您是否碰巧知道在 Windows 和 AIX 上的等价物... :-) ?
    • Windows 不应该有这个问题(符号已经默认隐藏在那里,除非你用declspec(dllexport) 标记它们)。没有 AIX 专业知识,但如果我正确阅读了 this,它支持 Linux 等版本脚本。
    • 您的解决方案确实有效,谢谢。但是我发现了一个更简单的方法:只需将“--exclude-libs ALL”添加到链接行,这将使所有嵌入式静态库成为本地库。
    猜你喜欢
    • 2021-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多