Android开发我们主要用到的编译器是Java的Java编译器以及C/C++的gcc/clang编译器。对应Java层构建工具最初是Ant,后面Maven以及gradle;C/C++构建工具主要是make/cmake,做过系统开发或者chromeium,可能还用过ninjia、gclient、mm等。最近在编译Android平台的tensorflow lite库,发现官方使用的是Bazel构建工具,大概了解了下,它不仅可以构建Native层还可以构建Java层库。今天我们简单介绍下什么是Bazel,后续我们逐步深入了解Bazel构建工具,使用Bazel构建我们的Android项目。
Bazel概述
Bazel是一个开源的构建和测试工具,类似于Make、Maven和Gradle。它使用人类可读的高级构建语言。Bazel支持多种语言的项目,并为多种平台构建输出。Bazel支持跨多个存储库和大量用户的大型代码库。
为什么选择Bazel?
Bazel构建工具有以下优势:
- 高级构建语言。Bazel使用一种抽象的、人类可读的语言来在高级语义级别描述项目的构建属性。与其他工具不同,Bazel操作的是库、二进制文件、脚本和数据集的概念,避免了编写对编译器和连接器等工具的单独调用的复杂性。
- Bazel快速可靠。Bazel将缓存所有以前完成的编译结果,并跟踪对文件内容和构建命令的更改。这样,Bazel可以知道什么时候需要重建,而且只重建该处改动。还可以将项目设置为以高度并行和增量的方式进行构建以进一步加快构建速度。
- Bazel是跨平台的。Bazel可以在Linux、macOS和Windows上运行。Bazel可以从同一个项目中为多个平台(包括桌面、服务器和移动)构建二进制文件和可执行文件。
- Bazel是规模化的。Bazel在处理带有100k以上源文件的构建时保持了敏捷性。它可以与数以万计的多个存储库和用户群一起工作。
- Bazel是可扩展的。它支持许多语言,您可以扩展Bazel以支持任何其他语言或框架。
Bazel使用教程
要使用Bazel构建或测试一个项目,我们需要怎么操作呢?通常需要做以下操作:
- 设置Bazel环境。下载并安装Bazel
- 设置工作空间,该目录是Bazel查找构建输入和build文件以及存储构建输出的目录。
- 编写一个BUILD文件,用以向Bazel描述要构建什么以及如何构建。
- 从命令行运行Bazel。
我们可以使用Starlark(一种特定于领域的语言)来声明构建目标,从而编写构建文件。
构建目标指定了一组Bazel将构建的输入构件以及它们的依赖项、Bazel将用于构建的构建规则,以及配置构建规则的选项。
构建规则指定Bazel将使用的构建工具,比如编译器和链接器,以及它们的配置。Bazel附带了许多构建规则,涵盖了受支持平台上受支持语言中最常见的工件类型。
除了构建之外,我们还可以使用Bazel运行测试和查询构建,以跟踪代码中的依赖项。
Bazel是如何工作的?
当我们运行构建或测试时,Bazel会做以下事情:
- 加载与目标相关的Build文件;
- 分析输入及其依赖关系,应用指定的构建规则,并生成动作图。
- 在输入上执行构建操作,直到生成最终的构建输出。
由于所有以前的构建工作都被缓存了,Bazel可以识别和重用缓存的工件,只重新构建或重新测试更改的内容。为了确保正确,我们可以设置Bazel以通过沙箱密封地运行构建和测试,最大限度地减少偏差和最大化复用性。
什么是动作图?
动作图表示构建工件、它们之间的关系以及Bazel将执行的构建操作。通过这个图,Bazel可以跟踪对文件内容的更改以及对操作(比如构建或测试命令)的更改,并知道之前已经完成了哪些构建工作。该图还使我们能够轻松地跟踪代码中的依赖项。