【问题标题】:Linking phase in distccdistcc 中的链接阶段
【发布时间】:2010-09-21 01:08:26
【问题描述】:

使用 distcc 构建项目时的链接阶段是在本地完成的,而不是像编译那样发送到其他计算机来完成,有什么特别的原因吗?阅读 distcc 白页并没有给出明确的答案,但我猜与编译相比,链接目标文件所花费的时间并不是很重要。有什么想法吗?

【问题讨论】:

    标签: c++ c gcc compiler-construction build-process


    【解决方案1】:

    distcc 的工作方式是在本地预处理输入文件,直到创建单个文件翻译单元。然后该文件通过网络发送并编译。在那个阶段,远程 distcc 服务器只需要一个编译器,它甚至不需要项目的头文件。然后将编译的输出移回客户端并作为目标文件在本地存储。请注意,这意味着不仅链接,而且预处理都在本地执行。这种工作分工对于其他构建工具很常见,例如 ccache(始终执行预处理,然后尝试使用先前缓存的结果解析输入,如果成功则返回二进制文件而不重新编译)。

    如果您要实现分布式链接器,则必须确保网络中的所有主机都具有完全相同的配置,否则您必须一次性发送操作所需的所有输入。这意味着分布式编译将产生一组目标文件,并且所有这些目标文件都必须通过网络推送,以便远程系统链接并返回链接的文件。请注意,这可能需要引用并存在于链接器路径中但不存在于链接器命令行中的系统库,因此“预链接”必须确定实际需要发送哪些库集。即使可能,这也需要本地系统猜测/计算所有真正的依赖关系并将它们发送给网络流量,并且实际上可能会减慢进程,因为发送的成本可能大于链接的成本 --if获取依赖项的成本本身并不像链接那么昂贵。

    我目前正在处理的项目有一个超过 100M 的静态链接可执行文件。静态库大小不一,但如果分布式系统认为最终的可执行文件是远程链接的,那么它需要的网络流量可能是最终可执行文件的三到五倍(模板,内联......所有这些都出现在所有包含它们的翻译单元,因此会有多个副本在网络中传播)。

    【讨论】:

    • 谢谢,这解决了一些问题。增加的复杂性和网络开销可能不值得实现分布式链接器,实际上它可能会使整个过程变慢。
    • 很抱歉没有启动一个旧线程,但如果节点实际上是同质的,它是否可以实现分布式链接?你知道现有的任何工具吗?您会更改答案中的任何内容以反映过去 6 年发生的变化吗?
    • @ffledgling:我不知道任何分布式链接器,老实说,我不认为这是一个可以轻松分布在不同机器上的操作,因为输出是单个文件,并且添加到二进制文件中的每个新目标文件都可能影响每个其他(稍后在链接行中)库的处理。
    【解决方案2】:

    几乎按照定义,链接要求您将所有目标文件放在一个位置。由于 distcc 首先将对象文件放在调用 distcc 的计算机上,因此本地计算机是执行链接的最佳位置,因为对象已经存在。

    此外,一旦您开始将库混入其中,远程链接就会变得特别麻烦。如果远程计算机将您的程序与其本地版本的库链接起来,那么当链接的二进制文件返回到本地计算机时,您就会发现潜在的问题。

    【讨论】:

      【解决方案3】:

      编译可以发送到其他机器的原因是每个源文件都是独立编译的。简单来说,对于每个.c 输入文件,都有一个来自编译步骤的.o 输出文件。这可以在任意多台不同的机器上完成。

      另一方面,链接收集所有.o 文件并创建一个 输出二进制文件。那里真的没有什么可以分发的。

      【讨论】:

      • 确实如此,但是否存在您要构建的项目最终包含多个程序集(exes、dlls)的情况?在那种情况下,整个构建时间不会从分配链接过程中受益吗?
      • 取决于实际执行分布式链接所需的操作。到目前为止,distcc 不需要远程服务器与客户端有 任何 共同(但编译器版本)。客户端进行预处理(消除对构建变量和标头的依赖)并通过网络发送单个预处理文件。该文件是自包含的,远程系统可以编译它而不需要任何其他文件。不提出要求,编译器必须通过网络发送所有对象文件和库,然后取回链接的对象。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      相关资源
      最近更新 更多