概览
以下样式和最佳实践适用于 Fuchsia 中的所有 Bazel 文件。
此页面是 Bazel 样式指南和最佳实践的一部分,其中 包含针对特定场景的其他指南。
源代码文件和依赖项列表的局部变量
虽然官方指南 不鼓励使用依赖项 变量,但 Fuchsia 允许使用 依赖项变量来管理大型共享源代码文件或依赖项列表。请考虑列表是否基本相似,或者是否仅共享一些常见项,以此进行练习。
不减法:切勿从列表变量中移除项。
请勿使用 glob()
请勿使用 glob() [SHAC 错误]。请改为明确列出文件。
fx build 从 Ninja 操作运行 Bazel,而 Ninja 仅跟踪 glob() 上次运行时匹配的文件。如果您添加了 glob() 现在会匹配的文件,Ninja 不会注意到。增量 build 和 fx test 运行会继续使用旧文件列表。明确列出文件时,添加文件意味着修改 BUILD.bazel 文件,而 Ninja 会跟踪该文件。
此规则特定于 Fuchsia。官方 Bazel 样式指南允许非递归 glob,并且在 Bazel 不再在 Ninja 中运行时,可能会再次允许使用非递归 glob。
build/bazel/shac/glob_allowlist.json
运行检查的每个代码库的根目录中列出了对 glob() 的现有使用情况(例如,
//build/bazel/shac/glob_allowlist.json 和
//vendor/google/build/bazel/shac/glob_allowlist.json)。
未经 build 团队批准,请勿添加新条目。系统不会检查 third_party/ 目录下的上游代码。
切勿使用递归 glob
无论是否涉及 Ninja,都不应在任何 Bazel 代码中使用递归 glob (**)。官方 Bazel 样式指南
禁止对源文件使用递归 glob。
它们会跳过包含自己的 BUILD.bazel 文件的子目录,因此很难确定它们匹配哪些文件。此外,它们在每个目录中的缓存和并行化效果不如 BUILD.bazel 文件。
唯一的例外是第三方库和其他代码库(例如 //vendor/... 代码库)的特定情况,在这些情况下,列出每个路径并不实际。在 third_party/ 目录之外,这些路径仍需要许可名单条目。
公开范围
以下是一般准则,适用于 BUILD.bazel 和 .bzl 文件。如需了解更具体的详细信息,请参阅每个文件的页面。
尽可能在 BUILD.bazel 和 .bzl 文件中指定公开范围
唯一支持该属性但不需要指定该属性的场景是软件包(目录)私有的宏。
请勿使用公开范围
请勿在 bazel_sdk/ 目录之外使用公开范围 ("//visibility:public" 或 visibility("public"))
。只有当代码被外部
代码库使用时,此访问级别
才适用,这不
适用于 fuchsia.git 中的非 SDK 代码。
公开范围应尽可能缩小,同时仍允许测试和反向依赖项访问
公开范围应仅限于需要该范围和/或应允许使用该范围的目标。请保持保守但实用。例如,如果目标在 //src 的五个直接子目录中使用,请考虑使用
//src:__subpackages__,以避免在添加新用途时需要修改公开范围。但是,如果目标仅应由驱动程序使用,请将其限制为实现驱动程序的软件包。
使用软件包组进行常见的非琐碎公开范围定义
如果多个目标的 visibility 应限制为同一组
标签,请考虑使用
package_group表示该组。package_group 在与目标一起使用时也
支持负公开范围,但与
加载公开范围一起使用时不支持。
请勿混用 SDK 和平台符号及目标
平台目标(即 AIB 或 IDK 中的所有内容)不得使用 Fuchsia Bazel 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/ 路径,但与 Fuchsia Bazel SDK 共享实现的特定 build 规则除外。
目标和 .bzl 文件的标签
引用目标
引用目标(例如,在 deps 中)时,只要不使用
禁止的标签模式,就允许使用以以下任一项开头的标签:
:- 仅对同一软件包(
BUILD.bazel文件)中的目标使用相对标签。
- 仅对同一软件包(
//- 如需了解例外情况,请参阅请勿使用 Fuchsia Bazel SDK 路径 。
@platforms//
从 .bzl 文件加载
Fuchsia 平台的大多数通用宏和规则都可以在 //build/bazel/rules/ 中找到。
只要不使用禁止的标签模式,就可以安全地从标签以以下内容开头的 .bzl 文件中 load():
:- 仅对同一软件包(目录)中的文件使用相对标签。
//- 如需了解例外情况,请参阅请勿使用 Fuchsia Bazel SDK 路径 。
@bazel_skylib//
还允许使用以下内容,但只有 build 团队的开发者可能会使用它们:
@fuchsia_build_config//:defs.bzl@fuchsia_build_info//:args.bzl@fuchsia_rules_common//
禁止的标签模式
请勿使用 [SHAC 错误]:
工作区根软件包标签(以
//:开头的标签)- 在非常特殊且非常罕见的情况下,需要使用此标签 (请参阅问题 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...
字符串
对字符串使用双引号,但为了避免转义而使用单引号的情况除外
默认情况下,对字符串使用双引号。 但是,如果
输出双引号更合适,并且这样做需要
转义双引号 (\"),请使用单引号
以避免转义。