函数

报告问题 查看源代码 敬上 每晚 · 7.3。 · 7.2。 · 7.1。 · 7.0。 · 6.5

目录

包裹

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

此函数用于声明适用于 软件包。它在软件包(BUILD 文件)中最多只能使用一次。

对于声明将元数据应用于整个 代码库中的示例,请使用repo() REPO.bazel 文件repo() 函数采用的参数与 package() 完全相同。

应在所有 load() 语句后调用 package() 函数, 文件。

参数

属性 说明
default_applicable_licenses

default_package_metadata 的别名。

default_visibility

标签列表;默认值为 []

此软件包中规则的默认可见性。

此包中的每个规则都具有此 属性(除非 visibility 中另有规定) 属性。如需详细了解此 API 的语法, 属性,请参阅关于 visibility 的文档。 软件包默认可见性不适用于 exports_files, 公开。

default_deprecation

String;默认值为 ""

设置默认 此软件包中所有规则的 deprecation 消息。

default_package_metadata

标签列表;默认值为 []

设置适用于软件包中所有其他目标的元数据目标的默认列表。 这些通常是与 OSS 软件包和许可声明相关的目标。 有关示例,请参阅 rules_license

default_testonly

布尔值;默认值为 False(另有说明的情况除外)

设置默认 testonly 属性。

javatests 下的软件包中,默认值为 True

features

列出字符串;默认值为 []

设置影响此 BUILD 文件语义的各种标记。

此功能主要供构建系统开发者用来 为需要特殊处理的软件包添加代码。除非 由构建系统工作者明确请求。

示例

以下声明声明,此软件包中的规则 仅对文件包的成员可见 群组 //foo:target。单独的可见性声明 如果存在,则覆盖此规范。
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

此函数定义了一组软件包 并将标签与集合相关联。您可在以下位置引用此标签: visibility 属性。

软件包组主要用于控制可见性。公开显示的 target 可以从源代码树中的每个软件包引用。私有 可见目标只能在其自己的软件包(而不是子软件包)中引用。 在这两种极端之间,目标可能会允许访问自己的软件包以及任何 一个或多个软件包组所描述的软件包。如需详细了解 有关可见性系统的说明,请参阅 可见性 属性。

如果指定软件包与 packages 属性,或已包含在其中一个属性中 includes 属性中提到的软件包组。

软件包组是技术上的目标,但并不是由规则创建的, 本身没有任何可见性保护。

参数

属性 说明
name

姓名;必需

此目标的唯一名称。

packages

字符串列表;默认值为 []

零个或多个软件包规范的列表。

每个软件包规范字符串都可以包含以下某一项 表单:

  1. 软件包的全名(不包含其代码库),以 双斜线。例如,//foo/bar 会指定软件包 具有该名称,并且与软件包位于同一代码库中 。
  2. 如上,但带有 /... 尾随。例如, //foo/... 指定 //foo 集合及其所有 子软件包。//... 指定当前软件包中的所有软件包 存储库
  3. 字符串 publicprivate, 分别指定每个软件包或无软件包。(此表单需要 将 --incompatible_package_group_has_public_syntax 标志 设置。)

此外,前两种软件包规范还可以 带有 - 前缀,表示被否定。

软件包组包含与至少一个项匹配的任何软件包 所有肯定性规范均未包含,且均未包含 例如,值 [//foo/..., -//foo/tests/...] 包含 //foo 的所有子软件包,但 //foo/tests 的子软件包。(//foo 本身为 而 //foo/tests 本身不包含。)

除了公开显示外,没有办法 当前代码库之外的软件包

如果缺少该属性,则等同于将其设为 这与将其设置为包含 只有 private

注意:在 Bazel 6.0 之前,规范 //... 具有与 public 相同的旧版行为。本次 行为是固定的, “--incompatible_fix_package_group_reporoot_syntax”现为 启用,这是在 Bazel 6.0 之后的默认设置。

注意:在 Bazel 6.0 之前的版本中,此属性会序列化为 “bazel query --output=proto”的一部分(或 --output=xml),系统会省略前导斜杠。对于 实例,//pkg/foo/... 将输出为 \"pkg/foo/...\"。在更新期间, “--incompatible_package_group_includes_double_slash”现为 启用,这是在 Bazel 6.0 之后的默认设置。

includes

标签列表;默认值为 []

此软件包中包含的其他软件包组。

此属性中的标签必须引用其他软件包组。 所引用软件包组中的软件包会纳入此 软件包组。这是传递信息 - 如果软件包组 a 包含软件包组 bb 包含软件包组 c,则包含 c也将成为“a”的成员。

当与否定软件包规范结合使用时,请注意 首先独立计算每组的软件包集合, 然后合并在一起。这意味着 对同一组中的规范没有任何影响 另一个群组。

示例

以下 package_group 声明指定 名为“tropical”的软件包组含有热带水果的水果。

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

以下声明指定虚构的 应用:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files() 指定一系列属于 导出到其他软件包

软件包的 BUILD 文件只能直接引用属于 导出到另一个软件包 exports_files() 语句。详细了解 文件的公开范围

作为一种传统行为,系统会同时导出规则输入中提及的文件 在标记之前, --incompatible_no_implicit_file_export 但是,您不应依赖上述行为,也不应主动 数据来源。

参数

参数是当前包中的文件名称列表。答 还可以指定可见性声明;在本示例中,这些文件将 对指定目标可见。如果未指定可见性,则文件 将对每个软件包可见,即使软件包默认可见性为 在 package 中指定 函数。许可 也可以指定它

示例

以下示例会导出 golden.txt, 来自 test_data 软件包的文本文件, 例如,在 data 属性中, 测试。

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

glob 是一个辅助函数,用于查找与特定路径模式匹配的所有文件, 并返回经过排序的可变的新路径列表。仅通过 glob 搜索文件 ,并且只查找源文件(既不是生成的文件, 其他目标)。

如果源文件的相对路径是相对路径,则结果中会包含该源文件的标签 路径与任意 include 模式匹配,但不匹配 exclude 格式。

includeexclude 列表包含路径模式 相对于当前软件包的出价每种格式都可能由一个或 更多路径细分。与 Unix 路径一样,这些段由 /。格式中的细分受众群与 路径。片段可能包含 * 通配符:此匹配 路径段中的任何子字符串(即使是空子字符串),不包括 目录分隔符 /。此通配符可以使用多次 在一个路径段中。此外,** 通配符可以匹配 零个或零个以上完整路径段,但必须将其声明为独立的 路径段。

示例:
  • foo/bar.txtfoo/bar.txt 文件完全匹配 (除非 foo/ 是子软件包)
  • foo/*.txt 会匹配 foo/ 目录中的每个文件 如果文件以 .txt 结尾(除非 foo/ 是 子包)
  • foo/a*.htm* 会匹配 foo/ 中的每个文件 以 a 开头,但可以包含任意字符串(可以 为空),然后包含 .htm,并以另一个任意字符串结尾 (除非 foo/ 是子软件包);例如 foo/axx.htmfoo/a.htmlfoo/axxx.html
  • foo/* 会匹配 foo/ 目录中的每个文件, (除非 foo/ 是子软件包);它与foo不匹配 目录本身,即使 exclude_directories 设置为 0 次
  • foo/** 会匹配每个非子软件包子目录中的每个文件 位于软件包的第一级子目录 foo/ 下;如果 exclude_directories 设置为 0、foo 目录本身也与模式匹配;在此示例中,** 被视为与零路径段匹配
  • **/a.txt 与此软件包的 a.txt 文件匹配 目录以及非子软件包子目录。
  • **/bar/**/*.txt 会匹配以下中的每个 .txt 文件: 此软件包的非子软件包子目录(如果 生成的路径称为 bar,例如 xxx/bar/yyy/zzz/a.txtbar/a.txt(请注意, ** 也与零个细分匹配)或 bar/zzz/a.txt
  • ** 会匹配以下项中的每个非子软件包子目录中的每个文件: 此软件包
  • foo**/a.txt 是无效格式,因为 ** 必须 独立成段
  • foo/ 是无效格式,因为已定义的第二个片段 / 后为空字符串

如果 exclude_directories 参数已启用(设置为 1),则 type 目录会从结果中省略(默认值为 1)。

如果 allow_empty 参数设置为 Falseglob如果结果为 空列表。

下面是一些重要的限制和注意事项:

  1. 由于 glob() 在 BUILD 文件评估期间运行, glob() 仅匹配源代码树中的文件,一律不匹配 生成的文件如果您构建的目标同时需要 则您必须明确地附上 复制到 glob。请参阅示例 下方显示了:mylib:gen_java_srcs

  2. 如果规则与匹配的源文件同名,则规则 “阴影”文件。

    为了理解这一点,请注意,glob() 会返回 因此,在其他规则中使用 glob()属性(例如 srcs = glob(["*.cc"]))与列出 匹配路径。例如,如果 glob() 生成 ["Foo.java", "bar/Baz.java"]中,但还有一条规则 名为“Foo.java”的软件包(这是允许的,但 Bazel 会发出警告), 那么 glob() 的使用者将使用“Foo.java”规则 (其输出),而不是“Foo.java”文件。请参阅 GitHub 问题 #10395 了解详情。

  3. glob 可能会与子目录中的文件匹配。以及子目录名称 可以带有通配符。但是...
  4. 标签不允许跨越软件包边界,而 glob 则跨越软件包边界 不匹配子包中的文件。

    例如,软件包中的 glob 表达式 **/*.cc 如果符合以下情况,则x不包含x/y/z.ccx/y 以软件包的形式存在(作为 x/y/BUILD 或软件包路径上的其他位置)。本次 而 glob 表达式的结果实际上取决于 是否存在 BUILD 文件,也就是说,相同的 glob 表达式将 如果未调用任何软件包,则包含 x/y/z.cc x/y,或使用 --deleted_packages 标志。

  5. 上述限制适用于所有 glob 表达式, 无论它们使用哪个通配符。
  6. 文件名以 . 开头的隐藏文件与 *** 通配符。如果您想匹配隐藏文件 ,则您的模式需要以 . 开头。例如: *.*.txt将匹配.foo.txt,但为*.txt 则不能。 隐藏目录也会以相同的方式进行匹配。隐藏目录 可能包含并不需要作为输入的文件, 不必要的全局性文件数量和内存消耗。排除 隐藏目录,请将它们添加到“排除”list 参数。
  7. “**”通配符有一种极端情况:模式 “"**"”与软件包的目录路径不匹配。也就是说, 例如,glob(["**"], exclude_directories = 0) 会匹配所有文件 和目录间接位于当前软件包的 目录下 (当然,不会进入子软件包的目录,请参阅 的备注)。

一般而言,您应尽量提供适当的扩展名(如 *.html) 而不是对 glob 模式使用裸“*”。更明确的名称 都是自行记录,确保您不会意外匹配备份 或 emacs/vi/... 自动保存文件。

编写构建规则时,您可以枚举 glob 的元素。本次 例如,支持为每个输入生成单独的规则。请参阅 扩展的 glob 示例部分。

Glob 示例

创建一个根据此目录中的所有 java 文件构建的 Java 库, 以及通过 :gen_java_srcs 规则生成的所有文件。

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

在目录 testdata 中添加除了 experiment.txt 之外的所有 txt 文件。 请注意,testdata 的子目录中的文件不包括在内。如果 如果您希望包含这些文件,请使用递归 glob (**)。

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

递归 Glob 示例

使测试依赖于 testdata 目录中的所有 txt 文件以及 其子目录(及其子目录等)。 系统会忽略包含 BUILD 文件的子目录。(查看限制 和注意事项)。

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

创建一个根据此目录下所有 Java 文件以及所有 Java 文件 子目录(路径包含名为 testing 的目录的子目录除外)。 应尽可能避免使用这种模式,因为它可以减少 从而增加构建时间。

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

扩展的 Glob 示例

在当前目录中为 *_test.cc 创建一个单独的 genrule 用于计算文件中的行数。

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

如果上面的 BUILD 文件在包 //foo 中,且包包含三个 匹配文件,a_test.cc、b_test.cc 和 c_test.cc,然后运行 bazel query '//foo:all' 将列出已生成的所有规则:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

select

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() 是用于生成规则属性的辅助函数 可配置。 它可以取代 差不多 因此其值取决于命令行 Bazel 标志。 例如,您可以使用它来定义特定于平台的依赖项或 根据规则是否内置于“开发者”中,嵌入不同的资源 对比“发布”模式。

基本用法如下:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

这样一来,就会将 srcs 属性设为 可通过替换普通标签进行配置的 sh_binary 使用映射的 select 调用列出分配 配置条件和值相匹配。每个条件都是一个标签 引用 config_settingconstraint_value, 哪些“匹配”如果目标的配置与期望的 值。然后,mytarget#srcs 的值会成为 标签列表与当前调用匹配。

注意:

  • 每次调用时,都只能选择一个条件。
  • 如果有多个条件匹配,并且其中一个条件是其他条件的专门属性, 因此该专精领域认证优先级较高条件 B 会被视为 条件 A 的特化(如果条件 B 具有相同的标志和约束条件) 以 A 的形式加上一些额外的标志或约束条件值。这也 意味着专用解析不是为了创建订单, 如下面的示例 2 所示。
  • 如果有多个条件匹配,但有一个条件并非针对所有条件 其他条件,则 Bazel 将失败并显示错误,除非所有条件都解析为相同的值。
  • 特殊伪标签 //conditions:default 如果没有匹配的其他条件,则视为匹配。如果此条件 必须匹配其他规则才能避免错误。
  • select 可以嵌入到内部 属性分配。因此,srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) 是有效表达式。
  • select 适用于大多数(但并非所有)属性。不兼容 属性在其文档中标记为 nonconfigurable

    子软件包

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() 是一个辅助函数,类似于 glob() 列出子软件包,而不是文件和目录。它使用与 路径模式为 glob(),并且可以匹配是 当前加载的 BUILD 文件的直接后代。如需查看关于包含和包含操作的详细说明和示例,请参阅 glob 排除格式。

    返回的子文件包按已排序顺序排列,且包含 与当前加载软件包的相对路径,该软件包与 include 而不是 exclude 中的那些。

    示例

    以下示例列出了软件包 foo/BUILD 的所有直接子软件包

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    

    一般而言,最好不要直接调用此函数, 用户使用“子软件包”此单元 skylib 相关联。