1
1
这个 根据需要 Linux链接中的分歧 您的示例:
表示您的linux发行版属于RedHat家族。让我们确认一下 比如CentOS 7:
所以你就在那里。 现在,让我们在Debian氏族发行版上查看它:
在这里,一切都是一样的:
当它变得不同时。现在链接无法解决
任何一个
具有
全部的
目标文件后提到的库-
Centos-7(RedHat)链接行为是老生常谈。Ubuntu 17.10(Debian) Debian 7于2013年引入了链接行为,并逐步推广 到Debian派生的发行版。如你所见,它废除了这种区别 在共享库和静态库之间, 或不需要显示在链接序列中 之后 所有输入 引用它的文件。它们都必须按依赖关系顺序出现(DO 1. ), 共享库和静态库相似。
这取决于发行版决定如何构建GCC版本
工具链-他们如何选择传递给系统的默认选项
链接器(
具体来说,这取决于链接器选项
如果
如果
在Debian 7之前,共享库链接的RedHat方式一直很流行
打破了等级。但是静态库的链接
总是
符合
根据需要
道德原则
默认情况下。没有
那又怎样? 因为Redhat way有着令人费解的区别——它是 外行的联系努力——问是很自然的 为什么? ,历史上, 是的 根据需要 对于静态库,但是 不按需要 对于共享库, 当然,这也是为什么它仍在红帽区。 链接器将程序(或共享库)组装为 增量填充 部分 和 动态依赖关系记录 (DDR 2. )在中 一种由节和DDR组成的结构,从空开始,然后 最终成为一个二进制文件,OS加载器可以解析并成功映射该文件 进入进程地址空间:例如ELF可执行文件或DSO。( 部分 这是一个真正的技术术语。 动态依赖关系记录 不是。 为了方便起见,我刚刚创造了。)
粗略地说,驱动此过程的链接器输入是对象文件,
共享库或静态库。但是
严格地
我说,他们是
任何一个
对象文件或共享库
. 因为静态库
一
当链接器到达一个对象文件时,该对象文件是 总是 链接的 进入程序。链接器从不询问 需要 对象文件 (不管这意味着什么)。任何对象文件都是无条件的 来源 悬挂机构的 进一步的投入必须满足的需求。
输入对象文件时,链接器必须将其分解为
这个
输入
并将其合并到
输出
程序中的节。当输入节
S
显示在一个对象中
文件,很可能是
S
将出现在其他对象文件中;
也许他们都是。链接器必须将所有输入缝合在一起
当共享库
使用对象文件是一种相对昂贵的链接;消费 共享库相对便宜-尤其是如果链接器没有 必须事先弄清楚共享库是否 需要 . 对象文件的输入/输出部分处理通常比写出DDR更麻烦。 但比工作更重要的是,链接一个对象文件通常会使程序变得非常重要 更大,以及 可以 任意放大。链接共享库添加 只有一个DDR,这总是一件小事。 因此,有一个值得尊重的理由,即链接策略可以拒绝 对象文件,除非需要,但允许链接共享库 没有必要。链接不必要的对象文件会添加任意数量的死区 程序的权重,在连杆上按比例加载。但是 如果链接器不必证明共享库 需要 ,然后它 可以在一瞬间将其链接到程序的大部分中,这一点可以忽略不计。如果开发人员选择将共享库添加到链接中,那么很可能需要它。红帽队 坎普仍然认为这个理由足够好了。
Debian阵营当然也有一个值得尊敬的理由。是的,Debian链接
需要额外的努力来确定
分裂中的每一方都有更棘手的利弊。
现在考虑链接器如何使用静态库,
很明显 根据需要 静态库的原则意味着DO。不 对象文件将从静态库中提取并链接,除非未解析 对对象文件定义的某个符号的引用已从 对象文件(或共享库) 已经 已链接。 静态库必须是 根据需要 ? 在RedHat land,共享图书馆在哪里可以免除DO,我们在哪里可以做什么 它的缺席只是 链接提到的每个共享库 . 正如我们所做的 可见,这在链接资源和程序大小方面相当便宜。如果我们 对于静态库,同样放弃DO,等效的策略将 收件人: 链接所提到的每个静态库中的每个对象文件 . 但是 这在链接资源和程序自重方面成本过高。 如果我们想为静态库释放DO,但仍然 不 链接 如果不需要对象文件,链接器如何继续? 也许是这样-
但这样的事不会发生。链接器 sees是链接的。这意味着对象文件的顺序 是相互联系的事物,即使是在两个不同的联系顺序之间 都是 成功的 .
假设对象文件
可能有
不止一个
订购
还不止这些。可能有多个订单
因此,每当链接器发现它在早些时候做出了类型2的选择时,它都需要 要回到这一点并尝试当时可用的其他选择之一, 它还没有试过 , 只有在尝试了所有方法都不成功的情况下,才能得出这种联系失败的结论。 像这样链接到 N 可选对象文件将按比例花费时间 到阶乘 N 失败。 像现在一样,使用DO for静态库,我们指定对象文件和/或静态库 Ij公司 在 链接器命令行的顺序如下:
这等同于对象文件的排序,为了论证,可能 注释:
哪里
不管我们是否知道 当我们编写命令行时,我们不仅要断言 与产量相关的良好做法排序 一些 程序,还有 这 排序生成我们需要的程序 打算 . 我们可能在第一个计数(=链接失败)上出错。我们甚至可能 第二个错误(=平均链接错误)。但如果我们不再关心这些的顺序 输入并将其交给链接器,以便找到一个好的解决方法,或者证明没有, 然后:
这是不会发生的。 难道我们就不能得到一个坏掉的东西的警告吗? 在一条评论中,你问为什么链接器至少不能 警告 如果我们的 静态对象文件和静态库不在DO中。 除此之外,这还将破坏这种联系,就像现在一样。但是给我们这个 附加警告链接器必须证明链接失败 因为对象文件和静态库不在DO中 ,而不仅仅是因为 链接中存在链接中没有定义的引用。还有它 只能通过证明 一些程序 可以通过对象文件和静态库的一些排列来链接。 这是一个阶乘规模的任务,我们不在乎 一些 可以链接程序, 如果程序 打算 链接不能是:链接器没有关于 除了我们提供的输入,我们打算链接什么程序 我们给他们。 如果提到任何库,很容易让链接器(或者更合理地说,GCC前端)发出警告 在命令行中的任何对象文件之前。但它会有一些讨厌的价值,因为 这种联系不一定会失败,事实上可能是有意的 悬挂机构。“对象文件之后的库”是很好的日常指南 通过GCC前端调用链接器。更糟糕的是,这样的警告只适用于 库之后的对象文件 不适用于DO断裂的情况 在库之间 ,因此它只能完成部分工作。 [1] 我的缩写。 [2] 也是我的缩写。 [3] 更准确地说,从静态库提取对象文件是递归的。 链接器提取定义未解析引用的所有对象文件 已经准备好了, 或 在 链接从库中提取的对象文件。 |
2
1
链接器加载库时
这就是为什么将库放在依赖它的对象文件之前将不起作用的原因。
根据经验,始终将库(甚至动态库)放置在命令行的末尾。按依赖关系的顺序。If模块(对象文件或库)
|
asendjasni · 在C中使用静态库 6 年前 |
Maneesh M · 如何在iOS应用程序中集成Atom支付网关? 6 年前 |
ImgPrcSng · 静态库中的符号可见性和操纵 6 年前 |
fionbio · 如何在iOS中链接protobufs 6 年前 |
PS_dev · 在目标C项目的静态库中获取框架头文件未找到错误 6 年前 |