.bzl 样式指南

报告问题 查看来源 每晚 · 7.2。 · 7.1敬上 · 7.0。 · 6.5 · 6.4

本页将介绍 Starlark 的基本样式准则, 有关宏和规则的信息

Starlark 是一个 定义软件构建方式的语言, 一种编程语言

您将使用 Starlark 编写 BUILD 文件、宏和构建规则。宏和 规则本质上属于元语言,它们定义了 BUILD 文件的写入方式。 BUILD 文件应简单明了且重复。

所有软件的读取频率都高于写入频率。对于 Starlark,工程师会阅读 BUILD 文件来了解其依赖项, 及其 build 的详细信息。这项读取操作通常是顺其而过, 或同时完成其他任务。因此, 简洁性和可读性非常重要 快速理解 BUILD 文件。

当用户打开 BUILD 文件时,他们会很快想知道 文件;或查看该 C++ 库的源代码列表;或移除 依赖项。每次添加抽象层时, 让用户更难完成这些任务

许多不同的工具也会分析和更新 BUILD 文件。工具可能无法 能够修改使用抽象的 BUILD 文件。保留您的BUILD 将有助于获得更好的工具。随着代码库规模的扩大 会越来越频繁地在多个 BUILD 文件中进行更改, 更新库或执行清理操作

总体建议

样式

Python 样式

如有疑问,请遵循 尽可能遵循 PEP 8 风格指南。 尤其是要缩进 4 个空格,而不是两个空格, Python 惯例。

开始时间 Starlark 不是 Python, Python 样式的某些方面并不适用。例如,政治公众人物建议 与单例进行比较的方法是使用 is,它不是 Starlark。

文档字符串

使用文档字符串记录文件和函数。 在每个 .bzl 文件的顶部使用一个文档字符串,并为每个公开文件使用一个文档字符串 函数。

记录规则和切面

规则和方面及其属性,以及提供商及其 字段,应使用 doc 参数进行记录。

命名惯例

  • 变量和函数名称均使用小写字母,单词由 下划线 ([a-z][a-z0-9_]*),例如 cc_library
  • 顶级不公开值以一条下划线开头。Bazel 会强制执行 不公开值。本地变量不应 请使用下划线前缀。

行长

与在 BUILD 文件中一样,由于标签可能很长,因此没有严格的行长度限制。 尽可能每行使用最多 79 个字符(遵循 Python 的 风格指南,PEP 8)。本准则 不应严格强制执行:编辑器应显示超过 80 列, 自动更改时往往会出现较长的行,而且人工更改不应该 花时间拆分可读的行。

关键字参数

在关键字参数中,等号两边最好有空格:

def fct(name, srcs):
    filtered_srcs = my_filter(source = srcs)
    native.cc_library(
        name = name,
        srcs = filtered_srcs,
        testonly = True,
    )

布尔值

首选值 TrueFalse(而不是 10)作为布尔值 (例如,在规则中使用布尔值属性时)。

请勿在正式版代码中使用 print() 函数;它只适用于 调试,并且会向您的 .bzl 文件的所有直接和间接用户发送垃圾内容。通过 唯一的例外是,您可以提交使用 print() 的代码(如果已停用) 但只能通过修改来源启用 print() 的使用受 if DEBUG: 的保护,其中 DEBUG 硬编码为 False。注意这些陈述是否有用,足以证明其合理性 它们对可读性的影响

宏是在加载过程中将一条或多条规则实例化的函数 阶段。一般来说,请尽可能使用规则,而不是宏。build 图表不是在测试期间 build - 在 Bazel 进行任何构建图分析之前会展开宏。

因此,如果出现问题,用户需要了解 宏的实现,以排查构建问题。此外,bazel query 的结果可能很难解读,因为结果中显示的目标 来自宏扩展最后,切面不识别宏,因此工具 可能失败。

您可以放心地使用宏,定义其他目标, Bazel CLI 或 BUILD 文件中直接引用:在这种情况下,只有 这些目标的最终用户需要了解它们,以及任何构建问题 而由宏引入的库也绝不会远离其用途。

对于用于定义生成的目标的宏(宏的实现详情) 不应在 CLI 中引用或被目标所依赖 不会由该宏实例化),请遵循以下最佳做法:

  • 宏应采用 name 参数并使用该名称定义目标。 该目标将成为该宏的主要目标
  • 生成的目标(即由宏定义的所有其他目标)应: <ph type="x-smartling-placeholder">
      </ph>
    • 其名称以 <name>_<name> 为前缀。例如,使用 name = '%s_bar' % (name)
    • 公开范围受限 (//visibility:private),并且
    • 使用 manual 标记以避免在通配符目标(:all...:* 等)。
  • name 只能用于派生由 宏,而不用于其他任何用途。例如,不要使用名称派生 并非由宏本身生成的依赖项或输入文件。
  • 在宏中创建的所有目标都应以某种方式与 主要目标。
  • 请确保宏中的参数名称保持一致。如果传递参数 作为属性值添加到主目标,则保持其名称不变。如果宏 参数的用途与常规规则属性相同,如 deps,采用与属性相同的名称(请参阅下文)。
  • 调用宏时,请仅使用关键字参数。这与 并大大提高可读性。

工程师通常会编写宏,因为相关规则的 Starlark API 无论规则是否 例如,在原生代码中的 Bazel 或 Starlark 中定义。如果您遇到这种情况 请询问规则制定者是否可以扩展该 API 以完成您的 目标。

一般来讲,与规则类似的宏越多越好。

另请参阅

规则

  • 规则、切面及其属性应使用小写名称(“蛇形” 案例”)。
  • 规则名称是名词,用于描述 从其依赖项的角度(对于叶规则, 用户)。不一定是文件后缀。例如,一条规则 会生成 C++ 工件,这些工件将用作 Python 扩展, py_extension。对于大多数语言,典型的规则包括: <ph type="x-smartling-placeholder">
      </ph>
    • *_library - 编译单元或“模块”。
    • *_binary - 生成可执行文件或部署单元的目标。
    • *_test - 测试目标。这可能包含多个测试。期待所有 测试在 *_test 目标中是同一主题的变体, 测试单个库
    • *_import:用于封装预编译工件(例如 .jar,或在编译期间使用的 .dll
  • 为属性使用一致的名称和类型。某些普遍适用的 属性包括: <ph type="x-smartling-placeholder">
      </ph>
    • srcslabel_list,允许文件:源文件(通常) 人工编写。
    • depslabel_list,通常不允许文件:编译 依赖项
    • datalabel_list,允许文件:数据文件,如测试数据等。
    • runtime_depslabel_list:不需要的运行时依赖项 以进行编译。
  • 对于任何具有不明显行为的属性(例如,字符串模板) 或以特定参数调用 要求),请使用 doc 关键字参数提供相关文档, 属性的声明(attr.label_list() 或类似值)。
  • 规则实现函数应几乎始终是私有函数 (以下划线命名)。一种常见的样式是为 myrule 的实现函数,名称为 _myrule_impl
  • 使用明确定义的 provider 接口。声明和文档提供程序 字段。
  • 设计规则时请考虑可扩展性。请注意,其他规则 与规则交互、访问提供商,以及重复使用 您创建的操作
  • 在规则中遵循效果指南