如何使用binutils链接器处理静态库之间的递归依赖?

Jac*_*oyd 15 linker dependencies gcc static-libraries binutils

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

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

当然是由时间链接器找到它需要从利巴符号的问题,它已经过去了吧,不会重新扫描,因此它只是出现了错误,即使符号是有服用.

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

处理这个问题的方法我考虑过:

  • 使用共享对象.不幸的是,从需要PIC补偿的角度来看这是不可取的(这是性能敏感的代码并且丢失%ebx以保持GOT真的会受到伤害),并且不需要共享对象.

  • 构建所有对象的一个​​巨大的ar,避免问题.

  • 重构代码以避免递归依赖(这显然是正确的事情,但我试图用最小的更改来做这个端口).

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

nos*_*nos 19

这样做:

g++ test_obj.o -lA -lB -lA       -o test
Run Code Online (Sandbox Code Playgroud)

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

  • 这个问题和那个答案是一个很好的例子,一个优雅的解决方案,盯着你的脸......它几乎像一个笑话的妙语...... :) (2认同)

fon*_*ons 10

虽然@nos提供了一个简单的解决方案,但是当涉及多个库并且相互依赖性更复杂时,它不会扩展.解决所ld提供的问题--start-group archives --end-group.

在您的特定情况下:

g++ test_obj.o --start-group -lA -lB --end-group -o test
Run Code Online (Sandbox Code Playgroud)