写点什么

Bazel 与 Gradle 构建工具差异对比

用户头像
轻口味
关注
发布于: 刚刚

之前介绍 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 标志在相同的提交时调用相同的构建,他们将看到相同的结果。增量构建和干净构建一样可靠,因此后者基本上是不必要的。

  • 性能:构建被设计成在给定可用资源的情况下尽可能快地执行。任务的并行性取决于它们的依赖链。不必要的工作永远不会执行(例如,“最新的”任务总是被跳过)。工作可以自然地分配给远程执行器,以克服本地机器的限制。

  • 再现性:构建的任何实例都可以在任何环境中容易的复现。例如,如果一个错误报告说软件 Y 的 X 版本在生产环境 Z 中失败,开发人员可以在自己的机器上容易地重新创建它,并相信他们正在调试相同的东西。

来自 Gradle 团队视角的说法

围绕构建自动化的全球对话非常热门。企业正在认识到,快速开发和改进软件的能力是在一个日益庞大和复杂的软件正在“吞噬世界”的环境中竞争的基础。关键驱动因素包括敏捷、SaaS 软件和 api、多渠道(如 Android、IOS、响应式 Web 等)、多语言软件(如 Scala、Go 等)、容器化(如 Docker)、微服务、用户分析(如最小可行产品方法、A|B 测试等)以及开放和封闭源库的混合。


所有这些紧急功能都需要系统来大规模协调分布式开发人员。随着 Bazel 的发布,谷歌加入了关于企业寻求实现高速构建自动化的重要问题的全球讨论。

为什么这样做?

构建领域应该由最聪明的人来做,并相互激励。企业构建系统中的新声音和解决方案可以加强这种全球对话;谷歌是一个才华横溢的工程组织,有着独特的视角。


在《财富》1000 强公司中,人们对硅谷的领先企业如何能够以极高的频率、如此迅速的创新构建大规模软件应用程序充满了好奇。来自这类公司的创新通常包含有价值的见解,这些见解可以在适当的时候转移到其他大型软件项目中。

Bazel 想解决什么问题?

Bazel 是内部谷歌构建系统的一个子集,称为 Blaze。因此,Bazel 已经进化到解决谷歌所特有的一个非常大的问题:


谷歌的 J. David Morgenthaler、Misha Gridnev、Raluca Sauciuc 和 Sanjay Bhansali 的这篇研究文章很好地记录了谷歌的情况:http://static.googleusercontent.com/media/research.google.com/en/us/pubs/archive/37755.pdf


最初的内部谷歌构建系统极大地影响了人们对构建的思考方式。在可扩展性方面,他们是真正的创新者。


与许多企业类似,谷歌有多种语言。但与大多数代码不同的是,谷歌对所有代码都有一个源存储库。所有的东西都频繁地从头部释放出来。这意味着没有办法改变团队之间的集成压力,以及跨组织边界(如位置、合作模型等)分离东西……再次强调,谷歌是这个星球上少数几个可以扩展这种模型的组织之一。当然,在这种情况下,如果没有彻底的并行化。但这是一个不同寻常的背景。


由于这个庞大的代码库,性能是第一位的,其他需求则是次要的,特别是那些与谷歌无关的需求。大多数公司不是谷歌,并且有更广泛的需求集。

Bazel 的贡献?

Bazel 的发明证实了世界上最好的软件公司非常关心构建自动化的核心能力。


对于那些想要比较 Gradle 和 Bazel 的人来说,Bazel FAQ 中最能说明问题的部分是他们团队对以下问题的回答:为什么谷歌不使用 Gradle?


来自 Bazel FAQ


Bazel 的配置文件比 Gradle 的要结构化得多,这让 Bazel 能够准确地理解每个操作的作用。这允许更多的并行性和更好的再现性。这里还需要注意的是,谷歌内部构建系统已经开发了 7 年多,所以自己构建自己的决定可能来自于更历史的比较。


这里有两个维度,一个是关于“更多的结构”和结果,从而增加并行性和更好的再现性。这两个最终目标在构建系统中都是非常理想的。


Bazel 所指的是低层执行和工具链模型。目前,Bazel 捕获了更多关于任务/动作的输入和输出之间关系的信息。这也使它能够在最低层次上可靠地并行化。这些都是配置模型的巨大改进,在并行环境中执行时可以提高构建性能。


关注并行化的谷歌可能是对构建性能的全局讨论中最大的讨论。做出如此深刻的投资来打造业绩,是一个伟大的行业领导行为。Gradle 的并行性不如如今的 Bazel。它是在项目级别上并行执行的,而不是在任务级别。但在接下来的几个月里,这将成为历史。有了我们即将推出的新配置和组件模型,Gradle 将会在最深层的层次上可靠且从根本上并行化,包括配置操作。


就结构而言,在许多方面,Gradle 提供了一个强大的模型,并考虑了更多并行性能方面的因素。在这些方面,Gradle 已经比 Bazel 更加结构化。尝试用 Bazel 创建一个变体感知 Android 构建,你会发现这是没有结构的。你回到了 Ant 的时代。基于这些原因,Gradle 将会是谷歌 Android 的默认系统。Android 团队选择 Gradle 的原因在于它与 Bazel(或者 Bucks 或 Pants)等工具的区别。它们是为了特定的环境和目的而创造的。


由于处理一个非常大的单片源存储库所需的并行性,谷歌在做出这个决定时显然需要构建自己的系统。但是在不久的将来,除了我们的其他设计特性和考虑事项外,Gradle 还会添加这个级别的并行性。

Gradle 是如何参与到这场对话中的?

Gradle 强烈地意识到,为了规范一组频繁出现的高度异构的项目、语言、平台、交付渠道和软件开发风格,需要在整个企业中建立标准的构建。我们也认识到,来自软件前沿的非凡技术和技术可以为世界其他地区做出巨大贡献。Gradle 已经从我们自己的客户,包括 Linkedin, Netflix,谷歌 Android 和许多其他客户那里看到了这种深深的承诺和领导力。


与谷歌 Blaze 团队一起,我们认识到单一多语言构建系统的作用,它为统一企业构建管道提供了一个融合的解决方案。然而,我们敏锐地意识到,大多数企业并不像谷歌那样采用单一的方法,而且大多数企业也没有谷歌所拥有的那种专门的构建服务团队和开发文化。为各种各样的企业客户提供服务,创造了设计需求,这些需求影响了 Gradle 的开发。


以下是通过研究 Bazel Alpha 可以得到的一些观察结果。


  • Bazel 没有使用一种高级的声明式使构建易于开发人员使用的构建语言。在谷歌,这可以通过拥有构建工具的专业服务团队来弥补。

  • 不是为可扩展性而构建的。由于 Bazel 仅为一个客户构建,如果谷歌的工程师需要深度扩展,他们有一个构建团队,可以将其融入到他们自己的工具中。

  • 速度是围绕着所有源传递依赖存储在一个大回购的想法进行优化的;所有的库和工具都签入到这个中央存储库中。大多数企业有更多的分布式依赖管理需求。

  • Bazel 是*nix only,它不运行在 Windows。这就排除了大量潜在的企业,包括一家最近被我们称为“51% . net”的大型银行。

  • 没有插件的生态系统。


Gradle 的目标一直是在性能、可扩展性、持续集成过程建模的丰富性和可用性之间找到最终的路径。


这个对话的另一个重要部分是关于构建工具链中各种工具的可扩展性和集成。首先,Gradle 与 Eclipse、IntelliJ 和 Android Studio 等流行的 IDE 系统进行了深度集成。除了这些深层次的 IDE 集成,Gradle 的生态系统是庞大的。插件门户网站有超过 300 +社区插件连接到各种工具,持续交付市场的平台和系统+更多在野外,下载 400 k /月,全球和精英群精英软件的提交者和一个强大的联盟组织,战略上使用它。

对话将向何处发展

关于构建自动化的全球讨论仍在继续。世界各地的开发人员都意识到有必要从分散的、不同的和不可维护的构建系统转向用于持续软件交付的统一范式。硅谷及其他地区的领先软件公司正围绕着软件的持续交付参与到行业游戏的升级中来。Gradle 很高兴能参与到这一全球性的讨论中来,并与世界级的企业合作,使它们能够拥有更大、更复杂的动态迭代软件的核心竞争力。


Gradle 已经有了许多令人满意的答案,这些答案统一了数百家领先的软件公司的构建系统。在接下来的几个月里,我们寻求改进的一个核心领域是重新架构我们的配置系统,这将为那些希望从 Gradle 的庞大生态系统和多样化特性集中获益的组织带来类似于 blaze 的并行化。


我们欢迎对我们即将到来的组件模型和分布式构建功能进行详细的审查,这些功能应该能够使 Gradle 通过开源为我们的客户和其他行业带来 google 级的分布式并行性。

Gradle 与 Bazel 针对 JVM 项目对比

gradle 团队针对 JVM 项目对 Gradle 与 Bazel 做了深入对比,尤其性能方面。

简介

Gradle 已经成为 JVM 生态系统中项目的首选构建工具,包括 Kotlin。它是 GitHub 上开源 JVM 项目最流行的构建工具。它平均每月被下载超过 1500 万次,并被 Techcrunch 列为 It 领域最受欢迎的 20 个开源项目。许多流行的项目已经从 Maven 迁移到 Gradle, Spring Boot 就是一个突出的例子。


最近,我们收到了关于在 JVM 环境中使用谷歌的 Bazel 构建工具的适用性的咨询。以下是对关键能力的详细比较性能分析和评估,得出三个主要结论:


尽管 Bazel 在性能和可伸缩性方面享有良好的声誉,但在我们测试的几乎所有场景中,Gradle 的表现都优于 Bazel。为 Bazel 优化项目需要花费大量的构建编写和维护成本。Gradle 为 JVM 项目中的常见用例提供了更吸引人的特性和便利。总之,数据和分析清楚地表明,对于大多数 JVM 项目来说,Gradle 是比 Bazel 更好的选择。我们将在后续文章中提供 Android 项目的等效比较。


同时,认识到单个工具在解决特定开发者生态系统和特定用例的需求和需求方面具有独特的优势,我们希望构建工具专业化和碎片化将继续成为这些生态系统(例如 Gradle 和 Maven)的规范。


认识到这一点,Gradle Enterprise 不仅为 Gradle 提供分析和加速功能。这允许用户从更快、更可靠的构建中获益,而无需迁移到任何特定的构建工具。现在包括了 Gradle 和 Maven,但是将来还会包括 Bazel 和其他工具。要了解更多关于 Gradle Enterprise 中支持的 Gradle、Maven 和 Bazel 构建工具的加速技术,请观看这个视频“加速 Maven 构建| Maven 构建缓存技术和业务案例解释”。

性能

构建系统对项目的执行情况取决于多种因素。这包括项目的大小和结构、使用的工具链和工作流程。在本节中,我们将描述进行性能比较的方法以及基于代表性场景的结果。

关于性能比较

在性能优化方面,Gradle 和 Bazel 有不同的方法和关注点。对于特定的性能场景,创建一些测试项目来显示 Gradle 比 Bazel 快得多,或者相反,是很容易的。问题总是在于这样的测试项目的结果对实际项目(更重要的是对您的项目)有多大的适用性。


我们进行比较的方法是对通用 Java 项目类型建模。从拥有数百万行代码的大型存储库到小型库/微服务项目。在本文中,我们不会讨论在单个大型源存储库中或跨许多较小的源存储库构建代码的各种方法的优缺点。这两种方法在 JVM 生态系统中都有很大的占用空间,通常在单个组织中也是如此。要从一种方法转换到另一种方法,就需要进行认真的迁移工作,并改变工作流程和文化。JVM 的构建系统应该很好地支持这两种方法。


对比完成构建场景下耗时,Gradle 对 Bazel 还是有一定优势的:



总结

从 Bazel 与 Gradle 两个团队的发声看,Bazel 更像是 Google 内部孵化出的针对公司内部自动构建的产物,而 Bazel 在一些场景(Android 编译,Java 编译以及 IDE 集成方面)更有优势,而且性能也会比 Bazel 更好。所以完全没有必要为 Gradle 的前途焦虑,它不会被替代。但是我们还有了解 Bazel 的必要吗?答案是肯定的,因为谷歌后续退出的一些产品会使用 Bazel 构建工具,了解 Bazel 有助于我们快速上手这些新产品。比如 TensorFlow 的源码编译就是基于 Bazel,后面我们针对移动端平台的 TensorFlow Lite 编译做一次分享。

参考

发布于: 刚刚阅读数: 2
用户头像

轻口味

关注

🏆2021年InfoQ写作平台-签约作者 🏆 2017.10.17 加入

Android音视频、AI相关领域从业者,开源RTMP播放器:https://github.com/qingkouwei/oarplayer

评论

发布
暂无评论
Bazel与Gradle构建工具差异对比