使用Bazel而不是Gradle的额外优势是什么?

shi*_*hen 12 android gradle android-testing android-gradle-plugin bazel

我正在阅读有关Android Testing Samples项目的文章,并注意到一个名为Bazel的" "构建工具正用于构建Android项目:

实验性Bazel支持

其中一些示例可以在Linux上使用Bazel构建.这些示例包含一个BUILD.bazel文件,类似于build.gradle文件.外部依赖项在顶级WORKSPACE文件中定义.

这是实验性功能.要运行测试,请按照Bazel网站上的说明安装最新版本的Bazel(0.12.0或更高版本).

然后,

  • 在现有的Gradle上使用Bazel的附加优势是什么?
  • 拥有适用于Android的TWO构建工具真的很棒吗?
  • 这是否意味着Android开发人员将来可能需要学习这种新的构建工具?

更新#1:更新了farhana的接受答案,感谢Jin提供有关google构建系统的详细信息.

更新#2:更新了谷歌代码实验室,用于bazel android介绍.

Far*_*ana 10

Bazel是内部Google构建系统Blaze的子集.因此,Bazel已经发展到解决了一个非常大的问题,这个问题在某种程度上(但可能并非完全)是Google特有的:

  • Bazel配置文件比Gradle更加结构化,让Bazel准确理解每个动作的作用.这允许更多的并行性和更好的再现性.

Bazel构建文件

Bazel使用两个配置文件:BUILDWORKSPACE

存在一个BUILD文件告诉Bazel它正在查看一个代码包 - 这个代码包包含当前目录及其中的所有子目录,除非该子目录包含一个构建文件.

在此输入图像描述

WORKSPACE文件是用BUILD语言编写的,和BUILD文件一样,包中只能有一个WORKSPACE.WORKSPACE文件的目的是跟踪项目的外部依赖项.每个外部依赖项都使用规则添加到WORKSPACE - 以下是一个示例:

在此输入图像描述

Gradle构建文件

Gradle构建系统使用多个文件:build.gradle,settings.gradle和gradlew.而不是像Bazel那样以脚本序列运行每个构建步骤,Gradle使用Groovy处理构建步骤配置,Groovy是一种与Java相关的面向对象语言.

build.gradle文件定义构建的配置和执行阶段,将两个使用对象分开.脚本的执行顺序定义如下:

在此输入图像描述

Bazel所做的事情包括:

  • 比特再现性.这是优秀的.

  • 与技术无关的内部包构建.你有一些依赖于某些C代码的python吗?有些Java需要javascript作为前端吗?Bazel可以做到这一点,它是少数可以开源的构建系统之一.

  • 通过其可重复性,Bazel可以缓存构建结果并仅重建其所需的内容.这使得它很快.

  • Bazel很灵活.它有自己的域语言,因此您可以扩展它以支持您需要构建的任何内容,无论创建者是否听说过它.想要"构建"(语法检查和测试)Javascript?Java?C?C++?目标C?Fortran语言?Brainfuck?没问题.如果尚未实现,则可以实现它.如果你不喜欢它的工作方式,你可以自己编写.想使用自定义编译器吗?自定义静态检查器?自定义测试工具?没问题.世界是你的牡蛎.

关于bazel不好

Bazel不是真正的依赖管理.它管理您的依赖项是什么,但不管理要使用的版本.如果您将整个依赖关系树中的所有内容都检入一个巨大的整体代码存储库(就像Google使用perforce的分支一样),那就没问题了."google方式"是指始终一直在构建所有内容,而不是依赖于旧版本.

结论:

这两种构建格式之间存在类似的功能级别,很明显这两种系统都是用不同的理念构建的.Bazel提供了一个易于推理的结构化系统,为大型和不断发展的产品提供了强大的功能基础.另一方面,Gradle提供了一个灵活,有状态,面向对象的界面,对于那些不经常使用脚本语言的人来说,这种界面可能会让人感到熟悉.

有关更多参考:


Jin*_*Jin 7

我是该存储库中Bazel支持的作者,并且在Bazel Android规则团队中工作。farhana已经写了一个了不起的答案,但我只想补充几点:

  • Bazel是Google内部使用的构建系统,这意味着它与构建YouTube,Gmail和照片之类的Google应用程序所使用的构建系统相同。
  • 其中一些Google应用程序非常庞大,Bazel需要很长时间才能在本地构建它们。因此,Bazel中有一个远程执行功能(在像Gradle一样的远程缓存之上,但具有更细粒度的IIUC),它使您可以将构建操作散发到远程执行者服务器场。Bazel具有静态且密封的动作依赖关系图,该动作图旨在完全可重现,每个动作都具有一组完全声明的输入,输出,环境变量,命令行,以及Bazel中有关配置,工具链和主机/目标的其他知识/执行平台。使用此图,Bazel可以安全地将操作分发给远程工作者,从而实现非常大的操作。并行度。我之前已经在Google Cloud Remote Build Execution上成功构建了500-800个并行作业的Tensorflow Android应用。
  • 自动化测试发现。Bazel的静态图还对测试,二进制文件/库和数据之间的依赖关系进行编码,因此在源文件中进行更改会自动使所有依赖于它们的测试无效。这告诉Bazel重新运行测试,如果不需要再次运行,则跳过缓存的测试。是的,您也可以在测试中使用远程执行,因此您可以同时运行数百到数千个测试。
  • Bazel可以构建多种语言:C ++,Go,Java,Scala,Rust甚至Haskell。它还可以构建iOS和Angular / TypeScript / JavaScript之类的客户端。这意味着您不需要像CMake这样的单独工具来构建NDK和C ++代码。您可以使用相同的构建工具来构建前端和后端,并一起运行集成测试。
  • Bazel具有一个称为的内置命令mobile-install,可用于快速迭代地开发Android应用程序。它会构建您的应用程序,分片本机库,dexes和资源文件,并且仅将更改的分片推送到设备以减少构建和部署时间。在此处了解更多信息

拥有两个Android版构建工具真的很好吗?

不仅仅是两个:Buck&Pants是另外两个流行的Android构建系统。每个构建系统都有其优点和缺点,并且被设计和实现为解决一组特定的需求。例如,Bazel(及其周围的工具生态系统)诞生于Google巨大的monorepo,因此它确实很好地解决了可伸缩性问题。

IMO可以选择尝试不同的方法是一件好事。

这是否意味着Android开发人员将来可能需要学习这种新的构建工具?

Bazel是开源的,并通过Bazel插件在Android Studio中提供支持。如果您觉得它有趣,请随时尝试!我们仍处于适应Android规则以在开放源代码世界中工作的早期阶段,因此希望某些功能目前仍在开发中。

  • @MarkHan准备好了:-) https://github.com/bazelbuild/rules_jvm_external (2认同)