巴塞尔和格拉德尔有什么不同?

Google 的构建工具 Bazel。这个工具和 格拉德尔有什么不同?什么是 Gradle 做不到的,什么是它做得更好的,什么是格拉德尔做得更好的?

40392 次浏览

免责声明: 我在 Bazel 工作,我并不是很熟悉 Gradle。然而,我的一个同事写了一篇关于这两个系统的比较文章,我在这里解释一下:

Bazel 和 Gradle 强调构建体验的不同方面。在某种程度上,它们的优先级是不相容的——格拉德对灵活性和不引人注目的渴望限制了它可以对构建结构施加的限制,而巴泽尔对可靠性和性能的渴望必然会强制执行不可协商的限制。

Gradle 和 Bazel 一样重视性能(增量构建、并行配置和执行、 Gradle 守护进程)、正确性(基于内容的“最新”检查)和可重复性(对声明性语法、依赖性版本控制、明确声明的依赖性的丰富支持)。Bazel 尊重灵活的项目布局的需要。

微妙之处在于,格拉德尔希望推广良好实践,而巴塞尔希望要求这样做。Gradle 的目标是在 Ant 体验(用不一致的结果自由定义您自己的项目结构)和 Maven 体验(强制执行最佳实践,没有不同项目需求的空间)之间找到一个中间地带。Bazel 认为,灵活的项目支持是可能的,而不需要牺牲使其强大的工作流成为可能的强有力的保证。

这两种哲学都不是更“正确”——无论哪种工具最适合一个项目,都取决于该特定项目的价值观。

格拉德尔概述

Gradle 是一个高度灵活的系统,使用户可以很容易地构建完整、可靠的构建流程,并且对他们如何组织项目的约束最小。它通过提供强大的构建块(例如,自动依赖跟踪和检索,紧密集成的插件支持)和一个通用的、图灵完成的脚本界面,可以按照用户的需要组合这些块。

格拉德尔强调了以下特点:

  • 易于从其他系统迁移。易于适应任何项目组织,易于实现任意的工作流结构。它本身理解 Ant 任务,并且本身与 Maven 和 Ivy 存储库集成。
  • 高度可扩展的脚本模型。用户通过编写 Groovy 脚本实现所有构建逻辑。“构建”只是泛型任务的依赖序列执行,泛型任务本质上是开放式的、可重写的、可扩展的方法定义。
  • 丰富的依赖管理。可以从外部代码存储库、本地文件系统和其他 Gradle 项目声明和自动暂存受版本控制的依赖项。构建输出也可以自动发布到存储库和其他位置。
  • 紧密集成的插件系统。插件只是简单地组织起来以促进所需工作流的任务包。Gradle 的许多“核心”功能实际上是通过插件实现的(例如 Java、 Android)。插件(根据自己的判断)与构建脚本逻辑紧密交互。插件可以深度访问 Gradle 的核心数据结构。

Bazel 概述

Bazel 的出发点是可靠而高效地构建 Google 内部项目。由于 Google 的开发环境异常庞大和复杂,Bazel 对其构建的完整性提供了异常强有力的保证,并且在实现这些构建时性能开销也异常低。

这为围绕可重复构建构建的强大开发工作流提供了基础,在这种情况下,“构建”成为一个抽象实体,可以被引用、重复、传递给不同的机器,并传递给任意的程序和服务,这样每个实例都是完全相同的。

Bazel 强调了以下特点:

  • 正确。Bazel 版本被设计为总是产生正确的输出,句号。如果两个用户在不同的机器上使用相同的 Bazel 标志在相同的提交中调用相同的构建,他们将看到相同的结果。增量构建和干净构建一样可靠,后者基本上是不必要的。
  • 表演。构建的设计目的是在有可用资源的情况下尽可能快地执行。任务的依赖链允许的并行性。不必要的工作永远不会被执行(例如,“最新的”任务总是被跳过)。工作可以自然地外包给远程执行器,以克服本地机器的限制。
  • 可重复性。构建的任何实例都可以在任何环境中忠实地复制。例如,如果一个错误报告说软件 Y 的版本 X 在生产环境 Z 中失败,开发人员可以在他们自己的机器上忠实地重新创建它,并确信他们正在调试相同的东西。

由于文章链接趋于消亡,这里是 格拉德小组对巴塞尔的看法的总结(大部分内容直接取自2015年3月发表的文章) :

它被设计用来解决一个 Google 独有的问题: 一个庞大的单一代码库(数亿 LOC)。

Bazel 目前提供的并行优势将与“我们即将推出的新配置和组件模型”相匹配(请记住这里的文章日期)。

Bazel 没有一种高级的声明性构建语言,使得构建对于开发人员来说很容易使用。在 Google,这可以通过拥有构建工具的专业服务团队来补偿。

Bazel 不是为可扩展性而构建的(尽管 Bazel 开发团队已经保证他们正在开发可扩展性)。

所有的传递依赖关系都存储在一个大的回购中,因此速度得到了优化; 所有的库和工具都签入到这个中央存储库中。大多数企业都有更多的分布式依赖管理需求。

Bazel 和 Gradle 都可用于 Linux、 Windows 和 macOS。

没有插件生态系统。

Gradle 主要用于 JVM eco 系统(Java、 Groovy、 Scala、 Kotlin... ...)。如果你的项目是在这个领域,你必须问的问题,格拉德或 Maven 将是一个更好的选择。为了排除 Gradle 构建的故障,您只需要与 Java 和 JVM 生态系统争论。

Bazel 的核心功能是检测增量更改(以及分布式构建缓存) ,并允许您做出反应,应用插件/规则来实现增量构建。要设置和维护这个系统,还需要了解一些 CPP、 Java 和 Python (Skylark)以及系统管理员的知识。同样,如果你必须问这个问题,我认为 Gradle 或 Maven 将是一个更便宜的投资。使用 Bazel,您可以以任何您定义的方式构建更强大的语言,但是需要付出代价。