bazel:如果已知构建图,为什么目标会不断增加

Set*_*ler 5 bazel

根据这个 doc,分析和执行阶段分别处理构建依赖树(除其他外)以及在需要时进行和执行工作。如果这是真的,我很好奇为什么目标的总数随着构建的进行而不断增加(即,当我开始一个大型构建时,bazel 可能会报告它构建了 100 个目标中的 5 个,但后来会说它构建了 20 个) 300 个目标,依此类推,分母增加一段时间直到趋于平稳)。

我听说加载和分析阶段可以混合使用。我可能不完整或不正确的理解是,当 bazel 解析 BUILD 文件时,会调用分析来确定命令行上请求的目标需要哪些依赖项,然后我想这会以某种方式传达回加载程序以拉入任何其他这些依赖项引用的 BUILD 文件,如果依赖项(以及 BUILD 文件)不在本地存储库中,则可能导致加载器出去并获取远程存储库。

然而,我的理解也是,虽然依赖图的动态构建是 bazel 未来的一个潜在方向,但目前,执行不会与分析混合,因此当执行开始时,完整的依赖树应该可供 bazel 使用(以及已知的目标总数)?bazel 是否有完整的树,但只是不想遍历树来计数以防它很大,或者这里发生了其他事情?

注意:我在这里找到了对这种现象的简要提及,但没有解释它为什么会发生。

Jin*_*Jin 5

您在进度条中看到的数字是指操作(命令行..ish)而不是目标(例如//my:target)。我写了一篇关于动作图的博客文章,这是关于它的相关描述:

动作图包含一组不同的信息:文件级依赖项、完整的命令行以及 Bazel 执行构建所需的其他信息。如果你熟悉 Bazel 的构建阶段,动作图是加载和分析阶段的输出,并在执行阶段使用。

但是,Bazel 不一定执行图中的每个动作。它仅在必须执行时才执行,也就是说,动作图是实际执行内容的超集。

至于为什么分母越来越大,那是因为动作图中的actions-to-execute发现是懒惰的。这是 Bazel TL 的更好解释,Ulf Adams:

问题在于 Skyframe 不会急切地遍历动作图,而是懒惰地遍历。这样做的原因是性能,因为动作图可能相当大,而这以前是一个阻塞操作(Bazel 会挂起一段时间)。缺点是所有遍历动作图的线程都会阻塞它们执行的动作,这会延迟对剩余动作的发现。这就是为什么这个数字在构建过程中不断上升的原因。

来源:https : //github.com/bazelbuild/bazel/issues/3582#issuecomment-329405311