【问题标题】:Interdependent Static Libraries [duplicate]相互依赖的静态库
【发布时间】:2019-07-05 11:54:13
【问题描述】:

假设我有两个静态构建的库。 libFoo.a 和 libBar.a.

libFoo.a 使用来自 libBar.a 的函数,而 libBar.a 也恰好使用来自 libFoo.a 的函数。

现在,让我们创建一个使用 libFoo 和 libBar 的程序 baz.cpp。通常,您会输入:

g++ baz.cpp -lfoo -lbar

但是,因为这两个静态库相互使用......我没有明显的解决方案来让编译时链接器接受这种情况并将它们链接在一起。

这是否是 C++ 标准所允许的明智和允许的事情?如果是这样,是否有一种非 hacky 的方式来处理这个问题?

或者首选的方法是将 libBar 和 libFoo 中的所有目标文件一起编译到一个静态库中?

【问题讨论】:

  • C++ 标准对库无话可说。处理此问题的通常方法是两次提及其中一个库-lfoo -lbar -lfoo
  • 我认为你可以运行两个libraries.a文件,至少在某些系统上是这样。当然,请注意,这对您的代码组织来说是一件非常奇怪的事情。
  • 我认为如果你有循环依赖,那么你的库设计就有缺陷。要么将两个库合并为一个,要么重构第三个库。
  • @Jonathon:我有几次循环依赖,即使在完全正交的设计中也是如此。考虑一个需要时间信息的日志库,而时间函数也需要记录错误的可能性。请注意,调用图中不一定存在循环依赖关系,您仍然存在链接器问题。

标签: c++ c linker


【解决方案1】:

有两种替代解决方案:

  • 重复库名称:-lfoo -lbar -lfoo
  • 使用链接器组:-Wl,--start-group -lfoo -lbar -Wl,--end-group

重复库名称的效果是链接器将库扔到当前未定义的符号处并解析它可以解析的所有内容,因此通过再次提及一个库,它将解析来自所有先前库的符号。这总是可以用来打破所有循环。

链接器组的效果是它有效地改变了链接器算法:它首先将组中的所有目标文件和库放入一个错误篮子,然后尝试解决所有问题(无论链接器组内的顺序如何),然后继续下一组。

【讨论】:

  • 第三种选择:解决两个库中明显的不良设计,要么将公共代码拉出到都依赖的第三个库中,要么将两者合并到一个库中。循环依赖通常表明内聚存在更大的问题
  • 一种选择是从每个库中提取所有目标文件,然后创建一个单独的libfoobar.a 库来保存它们。唯一容易出现的问题是如果有两个同名的目标文件,每个库一个。明智的重命名可以解决这个问题。
  • 链接器组对我来说听起来相当不错。谢谢约翰内斯。
猜你喜欢
  • 1970-01-01
  • 2021-12-12
  • 1970-01-01
  • 2010-10-22
  • 1970-01-01
  • 1970-01-01
  • 2012-06-21
  • 1970-01-01
相关资源
最近更新 更多