是否有任何特殊原因,在使用distcc构建项目时,链接阶段是在本地完成而不是像编译一样发送给其他计算机?阅读distcc白页并没有给出明确的答案,但我猜测链接目标文件所花费的时间与编译相比并不是很重要。有什么想法吗?
答案 0 :(得分:7)
distcc的工作方式是通过本地预处理输入文件,直到创建单个文件转换单元。然后通过网络发送该文件并进行编译。在那个阶段,远程distcc服务器只需要一个编译器,它甚至不需要项目的头文件。然后将编译的输出移回客户端并作为目标文件存储在本地。请注意,这意味着不仅可以在本地执行链接,还可以执行预处理。这种分工对于其他构建工具是常见的,例如ccache(总是执行预处理,然后它尝试使用先前缓存的结果来解析输入,如果成功则返回二进制而不重新编译)。
如果要实现分布式链接器,则必须确保网络中的所有主机具有完全相同的配置,否则您必须在一个批处理中为该操作发送所有必需的输入。这意味着分布式编译会产生一组目标文件,并且必须通过网络推送所有这些目标文件,以便远程系统链接并返回链接文件。请注意,这可能需要在链接器路径中引用和存在但在链接器命令行中不存在的系统库,因此“预链接”必须确定实际需要发送哪些库集。即使可能,这也需要本地系统猜测/计算所有真正的依赖关系并发送它们对网络流量产生很大影响,实际上可能会减慢流程,因为发送成本可能高于链接成本 - 如果获取依赖项的成本本身并不像链接那样昂贵。
我目前正在处理的项目有一个超过100M的静态链接可执行文件。静态库的大小不等,但如果分布式系统认为最终的可执行文件是远程链接的,那么网络流量可能要比最终可执行文件多三到五倍(模板,内联......所有这些都出现在所有包含它们的翻译单元,因此会有多个副本在网络中传播。)
答案 1 :(得分:2)
几乎按照定义,链接要求您将所有目标文件放在一个位置。由于distcc首先丢弃了调用distcc的计算机上的目标文件,因此本地计算机是执行链接的最佳位置,因为对象已经存在。
此外,一旦您开始将库放入混合中,远程链接将变得特别多毛。如果远程计算机将程序与其本地版本的库相关联,则在链接的二进制文件返回到本地计算机时,您已经解决了潜在的问题。
答案 2 :(得分:2)
可以将compliation发送到其他计算机的原因是每个源文件都是独立于其他源编译的。简单来说,对于每个.c
输入文件,编译步骤中都有一个.o
输出文件。这可以在任意多台不同的机器上完成。
另一方面,链接收集所有.o
个文件并创建一个输出二进制文件。在那里分发的确不多。