【问题标题】:The problem of link order when dynamic link libraries depend on each other动态链接库相互依赖时的链接顺序问题
【发布时间】:2021-08-23 01:49:00
【问题描述】:

对不起,我的英语不好。

GCC编译时,如果main.o依赖liba.so,而liba.so依赖libb.so

那么你应该先链接liba.so,然后再链接libb.so。反之则会出错

我学到的原因是:

编译器会依次遍历所有.o, .so模块,如果遇到未定义符号则放入列表U中

在依次遍历所有.o, .so模块的过程中,.o, .so中的符号用于解释列表U中的符号

遍历结束,如果U中还有未定义符号,则报未定义符号错误

所以如果liba.solibb.so相互依赖,理论上我需要像这样链接它们:

-la -lb -la

但是实际运行表明liba.so不需要链接两次

为什么?

是链接原理我学错了,还是编译器优化了

【问题讨论】:

  • 使用静态库,您可能需要按照您的假设进行操作。使用共享库,一旦使用一个符号,所有符号都可用,因此重复库是不必要的。现代链接器有一些选项可以自动重新处理静态库组。
  • 现代链接器有一些选项可以自动重新处理静态库组。 --> 这是否意味着我不需要关心我的静态库链接顺序? @JonathanLeffler

标签: c linux linker shared-libraries


【解决方案1】:

如果 main.o 依赖于 liba.so,而 liba.so 依赖于 libb.so
然后你应该先链接 liba.so,然后链接 libb.so。反之则会出错

你倒过来了:如果liba.so 依赖于libb.so,那么正确的链接顺序是-la -lb

但是实际运行表明liba.so不需要链接两次

为什么?

一般来说,对于 UNIX 链接器,顺序对于存档库很重要。

与存档库不同,在链接共享库时,您将获得整个库,因此如果它出现在链接行一次,则无需再次重复。

要了解为什么您可能需要在链接行重复存档库,请阅读this

是链接原理我学错了,还是编译器优化了

您所说的“原理”是错误的(向后),编译器根本不参与链接阶段。

【讨论】:

  • 谢谢,对我很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多