常见问题解答

报告问题 查看源代码

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

什么是 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 万个源文件,而未更改文件的构建大约需要 200 毫秒。

Google 为何不使用...?

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

Bazel 从何而来?

Bazel 是 Google 内部用来构建服务器软件的一个工具。此外,它还扩展了其他软件的构建范围,例如可连接到我们服务器的移动应用(iOS、Android)。

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

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

Google 为何构建 Bazel?

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

Bazel 是否需要构建集群?

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

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

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

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

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

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

您为什么开放 Bazel?

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

为什么我要使用 Bazel?

  • Bazel 可能会加快重新构建速度,因为它只能重新编译需要重新编译的文件。同样,它可以跳过它知道没有更改的重新运行测试。
  • Bazel 会产生确定性结果。这样可以消除增量 build 和干净 build、笔记本电脑和 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 内部,我们会把工具签入源代码控制系统,以实现可再现性。通过这种方式,我们可以对工具的更改(“将 GCC 升级到 4.6.1”)进行审核,其机制与对库所做的更改相同(“在 OpenSSL 中修复边界检查”)。

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

借助 Bazel,您可以使用 C/C++ 构建独立的静态二进制文件以及 Java 中独立的 JAR 文件。它们在普通 UNIX 系统上运行时很少依赖,因此应该在 Docker 容器中轻松安装。

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

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

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

Bazel 能否让我的构建自动重现?

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

  • 请勿使用未声明的依赖项。沙盒化执行(–spawn_strategy=sandboxed,仅适用于 Linux)可帮助您找到未声明的依赖项。
  • 避免将时间戳和用户 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 用于我的在此插入语言的项目吗?

Bazel 可扩展。任何人都可以添加对新语言的支持。系统支持多种语言:请查看 build 百科全书获取建议列表,访问 awesomebazel.com 查看更全面的列表。

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

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

请参阅我们的贡献准则

为什么开发工作没有完全开放?

我们仍然必须经常重构 Bazel 中的公共代码与内部扩展之间的接口。因此,在开放环境中进行大量开发工作变得非常困难。

完成 Bazel 开源工作了吗?

开源 Bazel 仍在开发中。具体而言,我们仍在努力开源:

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

除了代码之外,我们还希望最终将涉及 Bazel 社区的所有代码审核、错误跟踪和设计决策公开进行。我们尚未推出相关变更,因此某些更改只是简单地显示在 Bazel 代码库中,没有明确的解释。尽管透明度不够,但我们仍想支持外部开发者并开展协作。因此,虽然某些开发工作仍在 Google 内部进行,但我们仍开放了代码。在我们过渡到开放式模型时,如有任何不清楚或不合理的原因,请告诉我们。

Bazel 中是否有永远不会开源的代码部分?

是的,有些代码库要么集成了 Google 专有技术,要么一直在寻找各种理由来摆脱这些(或者说两者兼而有之)。GitHub 上不提供代码库的这些部分,并且可能永远不会提供。

如何与我们的团队联系?

我们的联系邮箱为 bazel-discuss@googlegroups.com。

在哪里报告错误?

在 GitHub 上打开问题。

代码库中的“Blaze”一词有什么变化?

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

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

在第一个(Alpha 版)版本之前,Bazel 无法从外部使用,因此 Chromium 和 Android 等开源项目无法使用它。此外,最初对 Windows 的支持不足是构建 Chrome 等 Windows 应用的问题。由于该项目已经成熟且更加稳定,因此 Android 开源项目正在迁移到 Bazel。

“Bazel”如何发音?

与美国英语中“basil”(香草)的用法相同:“BAY-zel”。它的押韵与“hazel”的押韵。IPA:/`beɪz`əl/