最佳做法

本页面假定您熟悉 Bazel,并提供了有关如何设计项目结构以充分利用 Bazel 功能的指南和建议。

总体目标包括:

  • 使用精细的依赖项来实现并行性和增量性。
  • 确保依赖项得到良好封装。
  • 使代码结构合理且可测试。
  • 创建一个易于理解和维护的 build 配置。

这些准则并非要求:只有少数项目能够遵守所有准则。正如 lint 手册页面所述,“第一个生成真实程序的人将获得一项特殊奖励,该程序在严格检查的情况下不会产生任何错误。”但是,纳入尽可能多的这些原则,应该能让项目更易于阅读、不易出错,且构建速度更快。

本页面采用此 RFC 中所述的要求级别。

运行构建和测试

项目应始终能够在其稳定分支上成功运行 bazel build //...bazel test //...。对于必要但在特定情况下无法构建的目标(例如需要特定构建标志、不在特定平台上构建、需要许可协议),应尽可能进行特别标记(例如“requires-osx”)。这种标记允许以比“手动”标记更精细的级别过滤目标,并且允许检查 BUILD 文件的人员了解目标的限制。

第三方依赖项

您可以声明第三方依赖项:

  • 请在 WORKSPACE 文件中将其声明为远程仓库。
  • 或者,将它们放在工作区目录下的 third_party/ 目录中。

依赖于二进制文件

所有内容都应尽可能从源代码构建。通常,这意味着,您需要创建一个 BUILD 文件并从其源代码构建 some-library.so,然后依赖于该目标,而不是依赖于库 some-library.so

始终从源代码构建可确保构建过程中使用的库不是使用不兼容的标志或其他架构构建的。还有一些功能仅适用于数据源,例如覆盖率、静态分析或动态分析。

版本控制

最好尽可能从头构建所有代码。当必须使用版本时,请避免在目标名称中包含版本(例如,//guava,而不是 //guava-20.0)。这种命名方式会使库更易于更新(只需更新一个目标)。它也更能应对菱形依赖项问题:如果一个库依赖于 guava-19.0,另一个库依赖于 guava-20.0,您最终得到的库可能会尝试依赖于两个不同的版本。如果您创建了一个误导性别名,将两个目标都指向一个 guava 库,则 BUILD 文件具有误导性。

使用 .bazelrc 文件

对于特定于项目的选项,请使用配置文件 workspace/.bazelrc(请参阅 bazelrc 格式)。

如果您希望项目支持您希望签入源代码控制系统的项目级选项,请添加以下行:

try-import %workspace%/user.bazelrc

(或任何其他文件名),然后将 user.bazelrc 添加到 .gitignoreworkspace/.bazelrc

软件包

每个包含可构建文件的目录都应该是一个软件包。如果 BUILD 文件引用了子目录(例如 srcs = ["a/b/C.java"])中的文件,则表示应将 BUILD 文件添加到该子目录。这种结构存在的时间越长,就越有可能无意中创建循环依赖项,目标的范围会不断蔓延,并且必须更新越来越多的反向依赖项。