它是静态库依赖关系树中的钻石问题吗?

时间:2017-04-12 16:51:46

标签: c++ compiler-errors linker static-libraries static-linking

我有一个困扰我的问题。我想我过去遇到过这个问题,但我无法在互联网上找到有关类似问题的信息。

假设我有:

  • a' common'库和它的两个不同的静态库:libcommon1.2.a和libcommon1.3.a。
  • ' extra-common'使用libcommon1.2.a并从中提供新的静态库的库。
  • 最终应用,使用最新的' common' (libcommon1.3.a)​​和最新的' extra-common' ('常见'' extra-common'已链接到该应用)。

如果在'普通'之间v1.3和v1.2只添加了新的组件,一切都应该没问题,对吧?

如果'普通' v1.3更改了' extra-common'使用的API,可能在链接' extra-common'时会出现遗漏符号问题。与应用程序的其余部分。

如果'普通' v1.3与v1.2保持相同的API,但是更改了一些内部结构,是否可能在运行时发生一些崩溃(由对象大小的变化或者vtable的更改等引起)?

你能给我发一些我可以google的条款,一些可能导致运行时崩溃的场景或一些文章链接?这样的术语就像"图书馆依赖中的钻石问题"?

我会感激不尽。

1 个答案:

答案 0 :(得分:3)

你在这里描述的(可能的)问题并不是你的依赖关系中有一个菱形结构,而是你正在使用依赖于libcommon1.2a的库(超常用),但你是而是反对libcommon1.3a。听起来你已经明白为什么这可能不安全了。

我认为您正在寻找的术语是ABI: application binary interface。它是编译代码的元素,必须在链接在一起的模块之间进行匹配,例如调用约定和结构布局。 ABI类似于API,但它与编译代码的兼容性而不是源代码有关。这两者是相互独立的:您可以在不破坏ABI的情况下中断API(例如,通过重命名结构中的字段),并且可以在不破坏API的情况下中断ABI(例如,通过更改数据类型的大小或重新排列字段结构)。

如果libcommon1.3a与libcommon1.2a不兼容ABI,则无法安全地使用额外的公共库。您需要使用libcommon1.3a头重新编译extra-common组件。 (如果1.3a也不是API兼容的,那么您可能还需要在特殊情况下进行更改。)