【问题标题】:Linking to a custom .a from multiple objects从多个对象链接到自定义 .a
【发布时间】:2014-05-27 05:57:09
【问题描述】:

在我们的构建系统中,我们生成多个 .so 文件(foo.so、bar.so、...),这些文件在运行时由主可执行文件 (biz) 加载。所以 .so 文件是单独链接的。

我们还有自己的 util.a 静态库,其中包含一些实用函数和全局数据。

当一些 .so 想要使用 util.a 数据/函数时,问题就出现了,但我们不能将每个 .so 链接到 util.a。这是因为数据部分:全局数据在程序地址空间中必须是唯一的。如果有多个 .so 链接到 util.a 并拥有一份数据副本,则程序行为将非常令人惊讶,但难以调试。

我们也无法将可执行文件 (biz) 链接到 util.a。链接器不会将所有内容都放到目标中,因为 biz 不会代表 .so 引用函数。

当然,除非将 util.a 与 -Wl,-whole-archive 链接。但是有没有更好的方法来做到这一点?

【问题讨论】:

  • 要么全存档,要么制作所有全局数据static,这样每个使用它的人都会拥有唯一的数据集。
  • 当您将.a 静态链接到您的.sos 时,这种令人惊讶的行为是什么?为什么很难调试?
  • @HAL .a 中定义的两个全局数据副本,具有相同的符号,会改变程序的行为并混淆调试器。
  • @keltar -Wl,-whole-archive 的便携性如何?如何断言所有全局数据都是静态的,以后不会误引入?
  • @FamZheng 整个存档的行为是明确定义的,但我不确定每个可能的链接器都支持这一点。最好将此库直接集成到程序源中,但如果使用-fvisibility=hidden 编译可能会引发问题。

标签: linux linker ld


【解决方案1】:

解决方案 1:考虑将 util.a 设为动态库 util.so。

解决方案 2:不要让链接器导出 util.a 导出的任何符号。使用 gcc 时,您可以通过使用 __attribute__((visibility("hidden"))) 来实现此目的:

int __attribute__((visibility("hidden"))) helperfunc(void *p);

您可以使用objdump 来检查导出了哪些符号。

【讨论】:

    【解决方案2】:

    为了回答我自己的问题,最终的解决方案是:

    http://lists.gnu.org/archive/html/qemu-devel/2014-09/msg00099.html

    TL;DR:使用nm (1) 在.so 对象中搜索所有有趣的符号(您想从档案中提取),并使用-Wl,-u,$SYMBOL 注入编译命令行。请注意,-Wl,-u,$SYMBOL 参数需要在命令行中位于存档名称之前,因此链接器知道它需要链接它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-21
      • 1970-01-01
      • 2019-02-22
      • 2016-11-25
      • 2018-04-10
      • 1970-01-01
      • 1970-01-01
      • 2016-01-26
      相关资源
      最近更新 更多