【问题标题】:How to deal with recursive dependencies between static libraries using the binutils linker?如何使用 binutils 链接器处理静态库之间的递归依赖关系?
【发布时间】:2011-02-13 20:41:37
【问题描述】:

我正在将现有系统从 Windows 移植到 Linux。该构建由多个静态库构成。我遇到了一个链接错误,在 libB 的对象中找不到符号(在 libA 中定义)。链接器行看起来像

g++ test_obj.o -lA -lB -o 测试

问题当然是当链接器发现它需要来自 libA 的符号时,它已经通过了它,并且不会重新扫描,所以即使符号在那里,它也会出错。

我最初的想法当然是简单地交换链接(到 -lB -lA),以便之后扫描 libA,并拾取 libA 中 libB 中丢失的任何符号。但是后来我发现libA和libB之间实际上存在递归依赖关系!我假设 Visual C++ 链接器以某种方式处理这个问题(默认情况下会重新扫描吗?)。

我考虑过的处理方法:

  • 使用共享对象。不幸的是,从需要 PIC 编译的角度来看,这是不可取的(这是对性能敏感的代码,丢失 %ebx 来保存 GOT 真的很糟糕),并且不需要共享对象。

  • 构建一个所有对象的巨型 ar,避免问题。

  • 重构代码以避免递归依赖(这显然是正确的做法,但我正在尝试以最小的更改完成此端口)。

您有其他想法来解决这个问题吗?有什么方法可以说服 binutils 链接器在缺少符号时重新扫描它已经查看过的库?

【问题讨论】:

    标签: gcc linker dependencies static-libraries binutils


    【解决方案1】:

    只要这样做:

    g++ test_obj.o -lA -lB -lA       -o test
    

    当链接器在命令行读取第一个 libA 时,它会丢弃其中尚未依赖的对象/符号,例如libB 需要但不是 test_obj.o 的所有符号。所以你只需让它再次读取 libA,它也会拾取这些符号。

    【讨论】:

    • 这个问题和那个答案是一个很好的例子,一个优雅的解决方案让你眼前一亮......它读起来几乎就像一个笑话的笑点...... :)
    【解决方案2】:

    虽然@nos 提供了一个简单的解决方案,但当涉及多个库并且相互依赖关系更复杂时,它就无法扩展。整理问题ld提供--start-group archives --end-group。

    在您的特定情况下:

    g++ test_obj.o --start-group -lA -lB --end-group -o test
    

    【讨论】:

    • g++ test_obj.o -Wl,--start-group -lA -lB -Wl,--end-group -o test
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 2023-03-29
    • 2011-12-12
    相关资源
    最近更新 更多