概览
以下样式和最佳实践适用于 Fuchsia 中的所有 Bazel 文件。
本页面是 Bazel 样式指南和最佳实践的一部分,其中包含针对特定场景的其他指南。
用于源文件和依赖项列表的局部变量
虽然官方指南不建议使用依赖项变量,但 Fuchsia 允许使用依赖项变量来管理大型共享源文件或依赖项列表。练习:考虑这些列表是基本相似,还是仅有一些共同项。
不减:一律不从列表变量中移除内容。
请勿使用 glob()
请勿使用 glob() [SHAC 错误]。请改为明确列出文件。
fx build 通过 Ninja 操作运行 Bazel,而 Ninja 仅跟踪与上次运行 glob() 时匹配的文件。如果您添加了现在与 glob() 匹配的文件,Ninja 不会注意到。增量构建和 fx test 运行随后会继续使用旧文件列表。如果明确列出文件,添加文件意味着修改 BUILD.bazel 文件,而 Ninja 会跟踪该文件。
此规则仅适用于 Fuchsia。官方 Bazel 样式指南允许使用非递归 glob,并且一旦 Bazel 不再在 Ninja 内部运行,它们可能会再次被允许。
glob() 的现有使用情况列在运行检查的每个代码库的根目录下的 build/bazel/shac/glob_allowlist.json 中(例如 //build/bazel/shac/glob_allowlist.json 和 //vendor/google/build/bazel/shac/glob_allowlist.json)。未经 Build 团队批准,请勿添加新条目。系统不会检查 third_party/ 目录下的上游代码。
切勿使用递归 glob
无论是否涉及 Ninja,都不要在任何 Bazel 代码中使用递归 glob (**) [SHAC 错误]。官方 Bazel 样式指南禁止对源文件使用递归 glob。它们会跳过包含自己的 BUILD.bazel 文件的子目录,因此很难判断它们匹配哪些文件。与每个目录中的 BUILD.bazel 文件相比,它们的缓存和并行化效果也更差。
唯一的例外情况是第三方库和其他代码库(例如 //vendor/... 代码库)的特定情况,在这些情况下,列出每个路径是不切实际的。在 third_party/ 目录之外,这些文件仍需要在 build/bazel/shac/recursive_glob_allowlist.json 中有一个条目,该条目与 glob() 许可清单是分开的。
公开范围
以下是适用于 BUILD.bazel 和 .bzl 文件的一般准则。每个页面上都提供了更具体的详细信息。
尽可能在 BUILD.bazel 和 .bzl 文件中指定可见性
唯一支持该属性且无需指定该属性的场景是宏对软件包(目录)而言是私有的。
请勿使用公开可见性
请勿在 //build/bazel_sdk/*rules*/... 目录之外使用公开可见性("//visibility:public" 或 visibility("public"))[SHAC 错误]。只有在代码由外部代码库使用时,此访问权限级别才合适,这不适用于 fuchsia.git 中的非 SDK 代码。
请勿引用供应商子路径
请勿在公开范围声明中包含供应商子路径或合作伙伴名称 [SHAC 错误]。在公开 Fuchsia 代码中,只能引用 //vendor:__pkg__、//vendor:__subpackages__、//vendor/google:__pkg__ 和 //vendor/google:__subpackages__(或 .bzl 负载可见性声明中的 //vendor/... 和 //vendor/google/...)。
可见性范围应尽可能小,同时仍允许测试和反向依赖项访问
可见性应仅限于需要和/或应允许使用它的目标。保守但务实。例如,如果某个目标在 //src 的五个直接子目录中使用,请考虑使用 //src:__subpackages__,以避免在添加新用途时需要修改公开范围。不过,如果目标应仅供驱动程序使用,请将其限制为实现驱动程序的软件包。
针对常见的非简单可见性定义使用软件包组
如果多个目标的 visibility 应限制为同一组标签,请考虑使用 package_group 表示该组。package_group 与目标搭配使用时也支持负可见性,但与加载可见性搭配使用时不支持。
请勿混用 SDK 和平台符号及目标
平台目标(即 AIB 或 IDK 中的所有内容)不得使用 Fuchsia Bazel SDK 中定义的符号、该 SDK 提供的目标或使用该 SDK 构建的目标。
反之亦然,使用 Fuchsia Bazel SDK 构建的目标不应依赖于平台目标,也不应从平台 .bzl 文件加载符号。
请勿使用 Fuchsia Bazel SDK 路径
平台代码绝不应访问包含 bazel_sdk 的文件路径或 Fuchsia Bazel SDK 代码库路径,例如:
@fuchsia_sdk//@internal_sdk//@rules_fuchsia//fuchsia
唯一允许的此类路径以 @fuchsia_rules_common/ 开头,但只有 Build 团队应直接使用这些路径。
平台代码还应避免使用 bazel_sdk/ 路径,除非特定 build 规则与 Fuchsia Bazel SDK 共享实现。
目标和 .bzl 文件的标签
引用目标
引用目标(例如在 deps 中)时,只要不使用禁止的标签模式,就允许使用以下列任何内容开头的标签:
:- 仅对同一软件包(
BUILD.bazel文件)中的目标使用相对标签。
- 仅对同一软件包(
//- 如需了解例外情况,请参阅请勿使用 Fuchsia Bazel SDK 路径。
@platforms//
从 .bzl 文件加载
Fuchsia 平台的大多数通用宏和规则都可以在 //build/bazel/rules/ 中找到。
只要不使用禁止的标签模式,就可以安全地从 .bzl 文件中 load() 标签以下列内容开头的文件:
:- 仅对同一软件包(目录)中的文件使用相对标签。
//- 如需了解例外情况,请参阅请勿使用 Fuchsia Bazel SDK 路径。
@bazel_skylib//
以下内容也允许使用,但可能只有 Build Team 的开发者会使用:
@fuchsia_build_config//:defs.bzl@fuchsia_build_info//:args.bzl@fuchsia_rules_common//
禁止的标签格式
请勿使用 [SHAC error]:
Workspace 根软件包标签(以
//:开头的标签)- 只有在非常特殊且非常罕见的情况下才需要这样做(请参阅问题 560343570),但通常只有 Build 团队才需要这样做。
软件包名称(即标签中冒号 [
:] 后面的部分)中包含斜杠 (/) 的标签。- 集成第三方库时,极少数情况下会有例外。
fuchsia_… 文件和符号位于 Fuchsia Bazel SDK 中
避免定义名称以 fuchsia_ 开头的文件、宏和规则。以 fuchsia_ 开头的现有名称可能属于 Fuchsia Bazel SDK(请参阅请勿使用 Fuchsia Bazel SDK 路径),避免使用此类名称有助于保持这种分离。
如需了解在需要区分 Fuchsia 平台与常规 Bazel 标识符时使用的一种模式,请参阅封装内置和常见规则、宏和函数。
使用 Fuchsia 专用封装容器
如果存在 Fuchsia 专用封装容器,请使用这些封装容器,而不是外部代码库、宏等。这有助于确保 Fuchsia build 配置得到一致应用。
具体而言,有适用于以下语言的封装容器:
C/C++:使用
//build/bazel/rules/cc/...中的fx_cc_...(),而不是@rules_cc//中的cc_...。Rust:使用
//build/bazel/rules/rust/...中的rustc_...(),而不是@rules_rust//中的rust_...。
Fuchsia 没有以下语言的封装容器。从以下路径加载,以确保一致性:
Go:
@io_bazel_rules_go//go...Python:
@rules_python//python...
字符串
对字符串使用双引号,除非是为了避免转义
默认情况下,请对字符串使用双引号。但是,如果输出双引号更合适,并且这样做会涉及对双引号 (\") 进行转义,请使用单引号以避免转义。