【问题标题】:Use of archive files for compilation: why, and is there any alternative?使用存档文件进行编译:为什么,还有其他选择吗?
【发布时间】:2012-03-28 23:32:32
【问题描述】:

在编译过程中,Linux内核创建liba.a,其中包含许多来自不同目录的built-in.o和其他目标文件,并将其作为最终vmlinux链接的主要组成部分。我在glibc 编译中看到了类似的归档文件使用,现在我想知道为什么这些项目使用归档文件以及这样做有什么好处。

据我所知,使用ar 生成的存档文件只是其中包含的各个文件的容器。除了减少每个目标文件的文件搜索时间之外,我没有看到使用它的太多好处。这是在编译过程中使用存档文件的原因吗?

如果是这样,我会惊讶于文件名搜索对内核人们关心的意义重大,我想知道不使用存档文件的成本是多少,以及如果没有空间的类似问题是否有任何替代方案.a 文件效率低下。

【问题讨论】:

  • 在编译命令中引用一两个库比引用 500 个目标文件更容易。
  • 您可以逐步添加到 .a 中。
  • @Duck 是的,它更容易参考,但这不是原因,我相信。内核人员通常对时间/空间资源的使用非常敏感,归档文件的这种可用性优势不能超过归档的时间开销和归档文件和目标文件的两倍空间开销。

标签: linux compilation kernel archive glibc


【解决方案1】:

回复:除了减少每个目标文件的文件搜索时间之外,我认为使用它没有太多好处。

您对好处的理解并不完全正确。档案减少了解析单个符号的工作量。

如果您从多个单独的.o 文件中链接一个程序,则链接器必须同时考虑所有这些文件。参考可以朝任何方向发展。命令行中最后一个.o 可以调用第一个.o 中的函数,反之亦然。

存档不是这种情况(至少默认情况下)。对于存档,早期存档中的函数只能引用其定义出现在后期存档中的符号。 (这也与传统的 Unix 约定有关,为什么 -l 链接器选项位于命令行末尾!!!首先是您的 .o 文件,然后是命令行。)

这意味着一旦出现定义符号的档案,您可以确定以后的档案不再使用该符号。这意味着您可以将其从数据结构中删除。您基本上已经“完成”了链接该特定库的工作;它已经满足了先前的引用,剩下的就是满足 ITS 未解决的引用。如果您对链接过程进行了正确的排序,并且软件分层很好,您可以随时减少未完成的符号数量。

Linux 已经有 20 多年的历史了,它的构建系统和代码一样有着悠久而丰富的历史。档案最初没有被使用;我认为这仅始于2.6。此外,依赖项曾经由 GNU awk 脚本生成。人们在 25 Mhz 386 和 4 兆 RAM 的机器上构建内核,哈哈。

现在使用存档是因为随着内核变得越来越大而需要存档。这不仅仅是为了它!

【讨论】:

  • 我说“默认”是因为有一种方法可以让链接器获取一组档案并在任何方向解析它们:破折号括号命令行参数。例如。 ld ... -\( libx.a liby.a libz.a -\)。破折号括号参数包含选定的档案组。如果档案有循环引用,它们是必要的。 GNU ld 手册页警告说,这可能会导致严重的性能损失。
  • 非常感谢您对链接器内部的详细回答!目标文件和档案处理的区别看起来很有趣,你的解释让我理解了我在 libc 编译中遇到的一些奇怪的事情(因为它在编译中也使用了很多档案..)
【解决方案2】:

我想到了几个原因:

为了扩展 Duck sez:“链接编辑器”(“ld”),又名“链接器”,(“man ld”)需要一堆编译的目标文件(.o 文件)和库( “存档”,正如您所说的那样)可以是“静态”库(.a 文件)或“共享库”(.so 文件),并将它们“链接”到“可执行文件”(“程序”)中。一个通过指定-l 选项的多次出现来告诉ld 要使用哪些库。想象一下,必须指定几千个 -l 选项,每个组件一个 .o 文件,而不是几十个或更少,每个库一个。

与某一功能领域相关的代码可以放入一个库中,以供其他代码使用和重用。比如/usr/lib/libcrypt.*提供加密能力,/usr/lib/libssl*提供Secure Socket Layer的支持代码等。

另外,我不知道 Kaz 是指哪个时间点,当她/他说“最初没有使用档案......”但“档案”,静态库,已经像 1983 年一样“最近”使用( !)。直到 90 年代初我才遇到动态共享库。

【讨论】:

  • 我想你还没有深入了解 Linux 内核(或 glibc)的编译过程。如果您看过它,您可能会理解我的问题的意图。这不是关于为什么存在库,而是关于为什么 linux 内核以特定方式使用它们。
  • 完全有可能我不明白“Linux内核(或glibc)编译”是什么意思,在这种情况下我的答案可能不会...... answer.here编译或链接内核没有什么神奇之处或 glibc 或任何其他库或可执行文件。同样的原则也适用。
猜你喜欢
  • 2019-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-27
  • 2015-08-22
  • 2011-04-21
相关资源
最近更新 更多