【问题标题】:linking to multiple versions of a static library链接到静态库的多个版本
【发布时间】:2012-12-18 10:52:34
【问题描述】:

我的项目链接到静态库 libA.a 版本 1。

此可执行文件还链接到另一个静态库 B。B 链接到 A,但版本 2。

A 的版本 1 和 2 中的两个符号集是相同的。 如果我知道我的项目和 B 之间没有共享任何与 A 相关的内容,这是否可行?

我设法手动链接它,它似乎工作(也许有我不知道的陷阱)。

我无法将库 B 设为共享对象,或将 A 用作共享对象。实际上,我只知道 B 静态使用 A 是因为我和写 B 的人交谈过。

【问题讨论】:

  • 你想知道这是否是一个好主意(它不是),或者对于特定的静态库(这是?),或者如何修复你的构建系统(失败怎么样?)...
  • 我认为你在这里一次问了太多问题。我会就多个版本提出这个问题,并就 CMake 方面提出一个单独的问题。
  • 您确定您的手动链接有效吗?链接器更有可能静默(甚至非静默)抑制两个库之一的冲突符号。
  • 我认为这只有在库 B 是共享库的情况下才能可靠地工作。这样,它就可以使用它喜欢的任何版本。
  • 您可以通过运行nmobjdump 来检查生成的二进制文件,并将其与两个静态库的输出进行比较。应该可以看到你最终使用了谁的符号。

标签: c linux linker cmake


【解决方案1】:

我有待纠正,但您似乎可以通过仔细的编译过程和明智地使用 objcopy 来完成您想要的。您应该遵循的步骤是:

  1. 编译 A. 的第 2 版。
  2. 针对 A2 编译库 B。
  3. 将 B 和 A2 合并到一个库 C 中(相关讨论请参见 this page)。
  4. 通过使用 objcopy 创建 C2,本地化 A2 中存在于 C 中的所有符号。使用objcopy --localize-symbols infile outfile,并查看here 了解详情。
  5. 编译版本 1 的 A.
  6. 编译您的应用 (P)。
  7. 链接 P A1 和 C2。

我在实践中从未这样做过,但所有构建块似乎都已到位。第 4 步是最难的,因为您必须识别所有冲突的符号 - 可能需要手动识别。

【讨论】:

    【解决方案2】:

    关于您问题的“链接”部分,实际上静态库没有链接在一起。链接步骤仅用于获取最终的可执行文件。

    事实上,您使用 A(版本 2)的标头编译您的静态库 B。然后将可执行文件与 B 和 A(版本 1)库链接。

    只要两个版本的 A 中的符号相同,就不存在编译问题。但是您必须知道您的可执行文件实际上只嵌入和使用 A 的版本 1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-13
      • 1970-01-01
      • 1970-01-01
      • 2011-03-15
      • 2011-03-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多