常见问题解答

如果您有疑问或需要帮助,请参阅获取帮助

什么是 Bazel?

Bazel 是一款可自动执行软件构建和测试的工具。受支持的构建任务包括运行编译器和链接器以生成可执行程序和库,以及组合适用于 Android、iOS 和其他目标环境的可部署软件包。Bazel 与 Make、Ant、Gradle、Buck、Pants 和 Maven 等其他工具类似。

Bazel 有什么特别之处?

Bazel 的设计宗旨是配合 Google 开发软件的方式。它具有以下功能:

  • 多语言支持:Bazel 支持多种语言,并且可以进行扩展以支持任意编程语言。
  • 高级构建语言:项目以 BUILD 语言描述,这是一种简洁的文本格式,将项目描述为相互连接的小型库、二进制文件和测试。相比之下,使用 Make 之类的工具时,您必须描述各个文件和编译器调用。
  • 多平台支持:您可以使用同一工具和相同的 BUILD 文件为不同架构甚至不同的平台构建软件。Google 使用 Bazel 构建各种内容,从在数据中心的系统中运行的服务器应用,到在手机上运行的客户端应用,不一而足。
  • 可再现性:在 BUILD 文件中,每个库、测试和二进制文件都必须完全指定其直接依赖项。Bazel 会使用此依赖项信息了解对源文件进行更改时必须重新构建的内容,以及哪些任务可以并行运行。这意味着所有构建都是增量的,将始终生成相同的结果。
  • 可扩展:Bazel 可以处理大型构建;在 Google,服务器二进制文件通常包含 10 万个源文件,未更改文件的 build 大约需要 200 毫秒。

Google 为什么不使用...?

  • Make, Ninja:这些工具可非常精确地控制调用哪些命令来构建文件,但用户可以自行决定编写正确的规则。
    • 用户在更高级别与 Bazel 互动。例如,Bazel 具有针对“Java 测试”、“C++ 二进制文件”以及“目标平台”和“主机平台”等概念的内置规则。这些规则经久不衰。
  • Ant 和 Maven:Ant 和 Maven 主要适用于 Java,而 Bazel 可处理多种语言。Bazel 鼓励在较小的可重用单元中细分代码库,并且只能重建需要重建的代码库。使用较大的代码库时,这可以加快开发速度。
  • Gradle:Bazel 配置文件的结构要比 Gradle 的更复杂,因而 Bazel 能够确切了解每个操作的作用。这样可以实现更高的并行性并更好地重现。
  • Pants, Buck:这两款工具分别由 Twitter、Foursquare 和 Facebook 的前 Google 员工开发和开发。它们是基于 Bazel 的模型构建的,但它们的功能集不同,因此对我们来说,它们不是可行的替代方案。

Bazel 来自哪里?

Bazel 是 Google 在内部构建其服务器软件时使用的一种工具。它还扩展到构建其他软件,例如连接到我们服务器的移动应用(iOS、Android)。

您是否将内部工具重写为开源工具?是叉子吗?

Bazel 将其大部分代码分享给内部工具,其规则每天用于数百万个 build。

Google 为何构建 Bazel?

很久以前,Google 使用生成的大型 Makefile 构建其软件。这些导致构建速度慢且不可靠,开始干扰了开发者的工作效率和公司的敏捷性。Bazel 是解决这些问题的一种方式。

Bazel 是否需要构建集群?

默认情况下,Bazel 会在本地运行构建操作。不过,Bazel 还可以连接到构建集群,从而加快构建和测试的速度。如需了解详情,请参阅关于远程执行和缓存远程缓存的文档。

Google 开发流程是如何运作的?

对于服务器代码库,我们使用以下开发工作流:

  • 我们的所有服务器代码都集中在一个巨大的版本控制系统中。
  • 每个人都使用 Bazel 构建软件。
  • 不同的团队拥有源代码树的不同部分,并将其组件作为 BUILD 目标提供。
  • 分支主要用于管理版本,因此每个人都在进行头版开发时开发软件。

Bazel 是这一理念的基石:由于 Bazel 要求完全指定所有依赖项,因此我们可以预测哪些程序和测试会受到某项更改的影响,并在提交之前对其进行审核。

如需了解 Google 开发流程的更多背景信息,请参阅 eng 工具博客

您为什么开放 Bazel?

构建软件应该既有趣又简单。缓慢且不可预测的构建让编程充满乐趣。

为什么要使用 Bazel?

  • Bazel 可以加快重新编译速度,因为它只能重新编译需要重新编译的文件。同样,它可以跳过已知未更改的测试,然后重新运行。
  • Bazel 会产生确定性结果。这样可以消除增量构建和干净构建、笔记本电脑和 CI 系统等之间的偏差。
  • Bazel 可以在同一个工作区中使用同一工具构建不同的客户端应用和服务器应用。例如,您可以在单次提交中更改客户端/服务器协议,并测试更新后的移动应用能否与更新后的服务器兼容,同时获得相同的工具,从而获得上述 Bazel 的所有优势。

我可以查看示例吗?

是;请参阅简单示例,或参阅 Bazel 源代码了解更复杂的示例。

Bazel 最擅长什么?

Bazel 基于以下属性构建和测试项目:

  • 具有大型代码库的项目
  • 以多种语言编译的项目
  • 在多个平台上部署的项目
  • 需要大量测试的项目

我可以在哪里运行 Bazel?

Bazel 在 Linux、macOS (OS X) 和 Windows 上运行。

只要平台支持 JDK,应该就能轻松移植到其他 UNIX 平台。

我不应该用 Bazel 做什么?

  • Bazel 会尝试明智地进行缓存。这意味着它不适合运行其输出不应缓存的构建操作。例如,不应从 Bazel 运行以下命令:
    • 用于从互联网提取数据的编译步骤。
    • 用于连接到您网站的质量检查实例的测试步骤。
    • 更改网站云配置的部署步骤。
  • 如果您的构建包含几个连续的冗长步骤,Bazel 可能无法提供这方面的帮助。将很长的步数分解成多个较小的离散目标,然后 Bazel 可以并行运行这些目标,从而提升速度。

Bazel 的功能集的稳定性如何?

核心功能(C++、Java 和 shell 规则)在 Google 内部广泛使用,因此经过了全面的测试,几乎没有流失。同样,我们会每天在数十万个目标上测试 Bazel 的新版本,以查找回归问题,并且每个月会多次发布新版本。

简而言之,除了标记为实验性的功能外,Bazel 应该功能正常。对非实验规则的更改将向后兼容。我们在我们的支持文档中提供了功能支持状态的详细列表。

Bazel 的二进制文件稳定性如何?

在 Google 内部,我们会确保 Bazel 崩溃非常罕见。我们的开源代码库也应如此。

如何开始使用 Bazel?

请参阅使用入门

Docker 不能解决可再现性问题吗?

借助 Docker,您可以轻松创建采用固定操作系统版本的沙盒,例如 Ubuntu 12.04、Fedora 21。这解决了系统环境的可再现性问题,即“我需要哪个版本的 /usr/bin/c++?”

Docker 不会解决与源代码更改相关的可再现性问题。如果在 Docker 容器中使用不完整的 Makefile 运行 Make,您仍然可以生成不可预测的结果。

在 Google 内部,我们会检查工具,以了解源代码的可再现性。通过这种方式,我们可以采用与基本库相同的机制(“将 OpenSSL 中的边界检查修复”)检查工具更改(“将 GCC 升级到 4.6.1”)。

我可以构建二进制文件来部署在 Docker 上吗?

借助 Bazel,您可以使用 C/C++ 构建独立的静态链接二进制文件以及 Java 版独立 JAR 文件。这些依赖项在普通 UNIX 系统上的依赖项极少,因此应该非常简单地安装在 Docker 容器中。

Bazel 具有用于构建更复杂的程序的惯例,例如,使用一组数据文件或将其他程序作为子进程运行 Java 程序。您可以将此类环境打包为独立的归档,以便部署在不同的系统(包括 Docker 映像)中。

我可以使用 Bazel 构建 Docker 映像吗?

是的,您可以使用我们的 Docker 规则构建可重现的 Docker 映像。

Bazel 能否让我的 build 自动重现?

对于 Java 和 C++ 二进制文件,是的,假设您不更改工具链。如果您的构建步骤涉及自定义配方(例如,通过规则内的 shell 脚本执行二进制文件),则您需要格外小心:

  • 请勿使用未声明的依赖项。沙盒化执行 (–spawn_strategy=sandboxed, only on Linux) 有助于找到未声明的依赖项。
  • 避免将时间戳和 User-ID 存储在生成的文件中。ZIP 文件和其他归档文件特别容易出现这种情况。
  • 避免连接到网络。沙盒化的执行功能也可为您提供帮助。
  • 避免使用随机数字的过程,特别是在许多编程语言中,字典遍历是随机的。

您是否有二进制文件?

可以,您可以找到最新的版本二进制文件并查看我们的版本政策

我使用 Eclipse/IntelliJ/XCode。Bazel 如何与 IDE 进行互操作?

对于 IntelliJ,请查看适用于 IntelliJ 的 Bazel 插件

如需了解 XCode,请参阅 Tulsi

对于 Eclipse,请查看 E4B 插件

对于其他 IDE,请参阅这些插件工作原理的博文

我使用 Jenkins/CircleCI/TravisCI。Bazel 如何与 CI 系统进行互操作?

如果构建或测试调用失败,Bazel 会返回非零退出代码,这应该足以实现基本的 CI 集成。由于 Bazel 不需要干净构建以实现正确性,因此在开始构建/测试运行之前,不应将 CI 系统配置为清理。

有关退出代码的更多详细信息,请参阅用户手册

我们预计会在 Bazel 中提供哪些功能?

请参阅我们的路线图

我可以使用 Bazel 处理 INSERT LANGUAGE HERE 项目吗?

Bazel 可扩展。任何人都可以添加对新语言的支持。系统支持多种语言,请查看 build 百科全书以查看建议列表;如需创建更全面的列表,请参阅 Awesomebazel.com

如果您想要开发扩展程序或了解其工作原理,请参阅有关扩展 Bazel 的文档。

我可以为 Bazel 代码库做贡献吗?

请参阅我们的贡献准则

为什么开发工作没有公开进行?

我们仍须频繁重构 Bazel 中公共代码与内部扩展之间的接口。因此,在开放环境中进行大量开发工作并不容易。

完成 Bazel 的开源工作了吗?

开源 Bazel 是一项仍在开发中的工作。具体而言,我们仍在努力开发开放源代码:

  • 我们的许多单元测试和集成测试(应该能够更轻松地贡献补丁程序)。
  • 全面的 IDE 集成。

除了代码之外,我们还希望最终公开所有代码审核、错误跟踪和设计决策,让 Bazel 社区参与进来。我们尚未实现,因此某些更改只是简单地显示在 Bazel 代码库中。尽管缺乏透明度,但我们仍希望支持外部开发者并与其展开协作。因此,即使 Google 内部仍在进行部分开发工作,我们也在开放代码。在我们过渡到开放模型时,如果有任何不明确或不合理的情况,请告诉我们。

Bazel 的某些部分永远不会开放开源吗?

是的,有些代码库要么集成了 Google 专有技术,要么一直在寻找借口来取代它(或者说两者兼而有之)。GitHub 上不提供代码库的这些部分,可能永远不会。

如何与该团队联系?

您可以发送电子邮件至 bazel-discuss@googlegroups.com 与我们联系。

在哪里报告错误?

GitHub 上打开问题。

代码库中的“Blaze”一词是什么?

这是该工具的内部名称。请将 Bazel 称为 Bazel。

为什么其他 Google 项目(Android、Chrome)会使用其他构建工具?

在第一个版本(Alpha 版)推出之前,Bazel 无法从外部使用,因此 Chromium 和 Android 等开源项目无法使用它。此外,最初还不支持 Windows 也在构建 Windows 应用(例如 Chrome)时出现了问题。由于此项目已日趋成熟并且越来越稳定,Android 开源项目正在迁移到 Bazel。

“Bazel”怎么说?

与美式英语中的“basil”(草药)相同:“BAY-zel”。它与“hazel”押韵。 IPA: /`be лz. {/4}