构建样式指南

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

BUILD 文件格式设置遵循与 Go 相同的方法, 工具可处理大多数格式问题。 Buildifier 是一种工具, 以标准样式发出源代码。因此,每个 BUILD 文件都是 这样,在上传过程中就不再出现格式问题了, 代码审核。它还使工具更易于理解、修改和 生成 BUILD 文件。

BUILD 文件格式必须与 buildifier 的输出一致。

格式设置示例

# Test code implementing the Foo controller.
package(default_testonly = True)

py_test(
    name = "foo_test",
    srcs = glob(["*.py"]),
    data = [
        "//data/production/foo:startfoo",
        "//foo",
        "//third_party/java/jdk:jdk-k8",
    ],
    flaky = True,
    deps = [
        ":check_bar_lib",
        ":foo_data_check",
        ":pick_foo_port",
        "//pyglib",
        "//testing/pybase",
    ],
)

文件结构

建议:请使用以下顺序(每个元素都是可选的):

  • 文件包说明(注释)

  • 所有 load() 对账单

  • package() 函数。

  • 对规则和宏的调用

构建器可以区分独立注释和注释 附加到元素。如果评论未附加到特定元素,请使用 后跟一个空行。在进行自动化测试时, 更改(例如,在删除规则时保留或移除评论)。

# Standalone comment (such as to make a section in a file)

# Comment for the cc_library below
cc_library(name = "cc")

对当前软件包中的目标的引用

文件应通过相对于软件包目录的路径进行引用 (无需使用向上引用,例如 ..)。生成的文件应该 前缀为“:”以表明它们不是来源。源文件 前缀不应为 :。规则应带有 : 前缀。对于 例如,假设 x.cc 是一个源文件:

cc_library(
    name = "lib",
    srcs = ["x.cc"],
    hdrs = [":gen_header"],
)

genrule(
    name = "gen_header",
    srcs = [],
    outs = ["x.h"],
    cmd = "echo 'int x();' > $@",
)

目标命名

目标名称应具有描述性。如果目标包含一个源文件 目标通常应具有派生自该来源的名称(例如, chat.cccc_library 可以命名为 chat,也可以命名为 java_libraryDirectMessage.java 可命名为 direct_message)。

软件包的同名目标(与 目录)所提供的功能, 目录名称。如果没有此类目标,请勿创建同名 目标。

提及同名目标时,更喜欢使用简称 (//x) 而不是 //x:x)。如果您在同一个软件包中,首选使用本地 引用(:x 而不是 //x)。

避免使用“预留”具有特殊含义的目标名称。这包括 all__pkg____subpackages__,这些名称具有特殊 并且可能会导致在使用时造成混淆和意外行为。

如果缺乏主要的团队惯例,则这些条款对团队没有约束力。 Google 广泛采纳的建议:

  • 一般情况下,请使用 "snake_case"
    • 对于包含一个 srcjava_library,这意味着使用的名称 与不带扩展名的文件名相同
    • 对于 Java *_binary*_test 规则,请使用 “Upper CamelCase”。 这样,目标名称就可以与其中一个 src 匹配。对于 java_test,这样就可以将 test_class 属性设为 。
  • 如果特定目标有多个变体,则向 消除歧义(例如:foo_dev:foo_prod:bar_x86:bar_x64
  • _test 目标添加 _test_unittestTestTests 后缀
  • 避免使用 _lib_library 等无意义的后缀(除非有必要 避免 _library 目标与其对应的 _binary 之间发生冲突)
  • 对于 proto 相关目标: <ph type="x-smartling-placeholder">
      </ph>
    • proto_library 个目标的名称应以 _proto 结尾
    • 特定于语言的 *_proto_library 规则应与底层规则 proto,但要将 _proto 替换为特定于语言的后缀,例如:
      • cc_proto_library_cc_proto
      • java_proto_library_java_proto
      • java_lite_proto_library_java_proto_lite

公开范围

公开范围应尽可能缩小范围,同时仍允许访问 由测试和反向依赖项构成。将 __pkg____subpackages__ 用作 适当的选择。

避免将软件包 default_visibility 设置为 //visibility:public//visibility:public只能为 项目的公共 API。这些库可能是专为依赖于 或二进制文件(可由外部项目的 构建流程

依赖项

依赖项应仅限于直接依赖项(依赖项 (规则中列出的来源所需)。请勿列出传递依赖项。

应首先列出软件包本地依赖项,并以某种方式引用它们 兼容 对当前软件包中的目标的引用 部分(而不是其绝对软件包名称)。

最好以单个列表的形式直接列出依赖项。将“常见” 将多个目标的依赖关系变为一个变量会降低可维护性, 工具不可能改变目标的依赖关系,这可能导致 未使用的依赖项

Glob

指明“无定位”尽在 []。不要使用没有任何匹配的 glob:它 比空列表更易出错,也不太明显。

递归

请勿使用递归 glob 来匹配源文件(例如, glob(["**/*.java"]))。

递归 glob 使 BUILD 文件难以推断,因为它们会跳过 包含 BUILD 文件的子目录。

递归 glob 的效率通常不如每个 glob 的 BUILD 文件 并在其之间定义了依赖关系图, 远程缓存和并行性

最好在每个目录中创建一个 BUILD 文件,并定义一个 它们之间的依赖关系图。

非递归

非递归 glob 通常可以接受。

其他惯例

  • 使用大写和下划线可声明常量(例如 GLOBAL_CONSTANT), 使用小写字母和下划线来声明变量(例如 my_variable)。

  • 不得拆分标签,即使标签长度超过 79 个字符也是如此。 标签应尽可能采用字符串字面量。理由:它使 轻松查找和替换。还可以提高可读性。

  • 名称属性的值应为字面量常量字符串(除 宏)。说明:外部工具使用名称属性来引用 规则。他们需要在无需解读代码的情况下查找规则。

  • 设置布尔值类型的属性时,请使用布尔值,而不是整数值。 由于旧版原因,规则仍会根据需要将整数转换为布尔值, 但我们不建议这样做原因flaky = 1 可能会被误读为 "通过重新运行一次来改善此目标的稳定性"。flaky = True含糊不清地说 “这个测试不太稳定”

与 Python 样式指南的差异

虽然 Python 样式指南 是目标,但两者之间有几点不同:

  • 没有严格的行长度限制。长注释和长字符串通常会被拆分 至 79 列,但这并不是必需的。不应在代码中强制执行 审核或提交前脚本。说明:标签可能很长,超过此限制 上限。通常由工具生成或修改 BUILD 文件, 就不太符合行长限制

  • 不支持隐式字符串串联。使用 + 运算符。 说明BUILD 文件包含许多字符串列表。我们很容易忘记 这会生成完全不同的结果。这导致了很多错误 是过去的日期。另请参阅此讨论。

  • 对于规则中的关键字参数,在 = 符号前后加空格。依据: 命名参数比 Python 中的使用频率要高得多,并且始终位于 换行。聊天室可提高可读性。该大会由 很长时间,因此不值得修改现有的所有 BUILD 文件。

  • 默认情况下,为字符串使用双引号。说明:这并非 Python 样式指南中指定的名称,但建议保持一致。我们 决定仅使用双引号字符串。许多语言都使用英文双引号 。

  • 在两个顶级定义之间添加一个空白行。依据BUILD 文件的结构与典型的 Python 文件不同。它只有 顶级语句。使用单个空白行可缩短 BUILD 文件。