【问题标题】:link with static library vs individual object files与静态库与单个目标文件的链接
【发布时间】:2011-02-06 06:31:28
【问题描述】:

出于某种原因,我想将静态库 (libx.a) 解压缩到单独的目标文件 (ao bo co) 中,并在链接器输入列表中指定这些目标文件 (ao bo co) 而不是 libx.a,使用其他链接器选项保持不变。

但是,我注意到上述更改导致输出可执行文件存在相当大的差异。基本上,(a.o b.o c.o) 方法会导致更大的输出大小。

那么这两种方法(libx.a 和单个目标文件)有什么区别? 有没有办法解决?

我使用的 GNU binutil (for and ar ld) 版本是 2.16.1

谢谢。

【问题讨论】:

  • 您试图通过拆分单个目标文件来完成什么?
  • 最初的原因是,我想在链接描述文件中为静态库指定输出部分。由于某种原因,存档语法 (libx.a:*.o(.text)) 不起作用,可能是由于我的工具链中的 binutil 版本过时。由于无法升级工具链,我不得不解压缩库并明确使用目标文件。这就是我遇到这个问题的原因。

标签: static linker


【解决方案1】:

Ld 删除链接的 .lib 档案中未使用的部分(如具有全局链接的变量)。当直接传递目标文件时,无法进行此优化,因为链接器无法确定 .o 文件的某些未引用元素是否需要稍后某些未知部分(例如,因为它对模块导出列表可见)或可以完全删除。在链接过程中放置​​ .lib 时,链接器肯定知道它可以删除不必要的元素。

【讨论】:

  • 我不怀疑你说的是真的,但一定是 ld 的 q quirk。据我所知,只要您处于最后的链接步骤,ld 应该能够对 .o 文件执行所有相同的死代码剥离,就像对 .a 文件一样。
  • .lib 和 .o 文件之间的区别在于 ld 将 .lib 文件中未引用的 .o 文件视为可丢弃,而每个 .o 文件都包含在输出中。这是因为存在特殊符号(例如 c++ 构造函数),它们被 ld 分组到特殊部分(即使它们未被引用)以执行特殊功能。还有一个开关(--whole-archive)可以从 .lib 文件中实例化每个未引用的 .o 文件,但我不知道是否有一个开关可以删除未使用的 .o 文件。
  • 谢谢大家。很高兴知道这一点。但这是否意味着如果我总是在链接最终可执行文件之前先将单个目标文件链接到静态库中,我更有可能获得更小的输出(如果有未引用的代码/数据)?如果这是真的,它可能是一种有用的技术(虽然听起来有悖常理)。回到我原来的问题(不能在链接器脚本中为静态库指定输出部分),有没有办法解决?谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多