之前介绍Bazel文章中有同学闻到Bazel与Gradle工具的差异。这篇文章我们解答这个问题。
来自Bazel员工的说法
Bazel和Gradle强调构建体验的不同方面。在某种程度上,它们的侧重点是互斥的——Gradle对灵活性和非突出性的要求对它的构建结构进行了限制,而Bazel对可靠性和性能的要求产生了强制不可协商的限制。
Gradle重视的原则和Bazel是一样的,也就是说,Gradle团队非常重视性能(增量构建、并行配置和执行、Gradle守护进程)、正确性(基于内容的“最新”检查)和可再生性(对声明式语法的丰富支持、依赖版本控制、显式声明的依赖关系)。Bazel尊重灵活的项目布局的需要。
区别在于,Gradle想要促进良好的实践,而Bazel想要要求它。Gradle的目标是在Ant经验(用不连贯的结果自由定义你自己的项目结构)和Maven经验(强制的最佳实践,不为不同的项目需求留有余地)之间找到一个中间位置。Bazel相信,灵活的项目支持是可能的,而不牺牲使其强大的工作流程保证,。
这两种哲学都不是绝对“正确”的——任何最适合项目的工具都取决于特定项目的价值。
Gradle概述
Gradle是一个高度灵活的系统,用户可以很容易地构建完整、可靠的构建流程,并且对如何组织项目的约束最小。它通过提供强大的构建块(例如自动依赖跟踪和检索,紧密集成的插件支持)和通用的、图灵完备的、脚本化的界面来实现这一点,用户可以按照自己的意愿组合这些块。
Gradle强调了以下特性:
- 易于从其他系统迁移。Gradle可以轻松地容纳任何项目组织,轻松地实现任意的工作流结构。它可以本地理解Ant任务,并本地集成Maven和Ivy存储库。
- 高度可扩展的脚本模型。用户通过编写Groovy脚本实现所有构建逻辑。“构建”仅仅是通用任务的依赖顺序执行,这些任务本质上是开放式的、可覆盖的、可扩展的方法定义。
- 丰富的依赖关系管理。版本化依赖项可以从外部代码库、本地文件系统和其他Gradle项目中声明并自动分段。构建输出同样可以自动发布到存储库和其他位置。
- 紧密集成的插件系统。插件是简单的任务包,组织起来以促进所需的工作流程。许多Gradle的“核心”特性实际上是通过插件实现的(例如Java, Android)。插件(由它们自己决定)与构建脚本逻辑紧密交互。插件可以深入访问Gradle的核心数据结构。
Bazel的概述
Bazel的发展源于可靠而高效地构建内部谷歌项目的需求。因为谷歌的开发环境非常大,非常复杂,所以Bazel对构建的完整性提供了非常强的保证,并且在实现构建过程中提供了非常低的性能开销。
这为围绕可复制构建构建的强大开发工作流提供了基础,其中“构建”成为一个抽象实体,可以引用、重复、传递给不同的机器,并传递给任意的程序和服务,这样就可以知道每个实例都是完全相同的。
Bazel强调了以下特点:
- 正确性:Bazel构建被设计成总是产生正确的输出,就是这样。如果两个用户在不同的机器上使用相同的Bazel标志在相同的提交时调用相同的构建,他们将看到相同的结果。增量构建和干净构建一样可靠,因此后者基本上是不必要的。
- 性能:构建被设计成在给定可用资