创建变量

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

“制作”变量是一种特殊的类,可展开字符串变量, 标记为“取决于‘创建变量’的属性”替换”

例如,这些文件可用于将特定的工具链路径注入 由用户构建的构建操作。

Bazel 提供了两种预定义变量,供所有用户 目标以及在依赖项目标中定义的自定义变量 并且只适用于依赖于这些变量的目标。

出现“品牌”一词的原因是历史: 这些变量最初旨在与 GNU 相匹配, Make

使用

被标记为“取决于‘创建变量’的属性”替换” 您可以参阅变量 FOO,如下所示:

my_attr = "prefix $(FOO) suffix"

换句话说,与 $(FOO) 匹配的任何子字符串都会扩展 设置为 FOO 的值。如果该值为 "bar",则最终 字符串变为:

my_attr = "prefix bar suffix"

如果 FOO 与使用方已知的变量不对应 目标,则 Bazel 会失败并显示错误。

“制作”变量的名称是非字母符号,如 @,也可以仅使用美元符号进行引用,无需使用 括号。例如:

my_attr = "prefix $@ suffix"

$ 编写为字符串字面量(也就是说,为了防止变量 扩展),写 $$

预定义变量

预定义的“品牌”变量可以由任何标记为 “取决于‘创建变量’替换”

查看这些变量列表及其指定一组 build 的值 选项, 运行

bazel info --show_make_env [build options]

看看最上面的输出行是否显示大写字母。

查看预定义变量的示例

工具链选项变量

路径变量

  • BINDIR:为目标生成的二元树的基数 架构。

    请注意,在 在主机架构上构建,以支持交叉编译。

    如果要从 genrule 中运行工具, 获取其路径的推荐方法是 $(execpath toolname), 其中,toolname 必须列在 genruletools 属性。

  • GENDIR: 为目标架构生成的代码树的基础。

机器架构变量

  • TARGET_CPU: 目标架构的 CPU,例如k8

预定义的 Genrule 变量

以下功能专为 genrulecmd 属性,并且 这对确保该属性有效通常非常重要。

查看预定义 Genrule 变量的示例

  • OUTSgenruleouts 列表。如果您有 只有一个输出文件,您也可以使用 $@
  • SRCSgenrulesrcs 列表(或更多) 也就是与 srcs 列表)。 如果您只有一个源文件,也可以使用 $<
  • <SRCS(如果是单个文件)。其他触发器 出现构建错误。
  • @OUTS(如果是单个文件)。否则,会触发 构建错误。
  • RULEDIR:目标的输出目录,即 与包含目标的软件包的名称对应的目录 位于 genfilesbin 树下。对于 //my/pkg:my_genrule,此字段始终以 my/pkg 结尾, 即使 //my/pkg:my_genrule 的输出位于子目录中也是如此。

  • @D:输出目录。如果 outs有一个条目 这将扩展为包含该文件的目录。如果有多个 条目,则会展开为 genfiles 树,即使所有输出文件都位于同一目录下,也会如此 子目录

    注意:请使用 RULEDIR 而不是 @D,因为 RULEDIR 的语义更简单,行为方式相同 而无需考虑输出文件的数量

    如果 Genrule 需要生成临时中间文件(例如 使用编译器等其他工具而产生的结果),则应尝试 将它们写入 @D(尽管 /tmp 也会 可写入),并在完成之前将其移除。

    尤其要避免写入包含输入的目录。他们可能已开启 只读文件系统即使不会,这样做也会破坏源代码树。

预定义的来源/输出路径变量

预定义变量 execpathexecpathsrootpathrootpathslocationlocations 采用标签参数(例如 $(execpath //foo:bar))并替换由该标签表示的文件路径。

对于源文件,这是相对于工作区根目录的路径。 对于作为规则输出的文件,这是文件的输出路径 (请参阅下文中输出文件的说明)。

请参阅预定义路径变量的示例

  • execpath:表示 execroot 运行构建操作的位置

    在上面的示例中,Bazel 会运行所链接目录中的所有构建操作 由工作区根目录中的 bazel-myproject 符号链接指定。通过 源文件 empty.source 链接到以下路径 bazel-myproject/testapp/empty.source。所以其执行路径(也就是 是根目录下的子路径)为 testapp/empty.source。本次 是构建操作可用于查找文件的路径。

    输出文件也以类似方式暂存,但还带有子路径前缀 bazel-out/cpu-compilation_mode/bin(或者, 工具:bazel-out/cpu-opt-exec-hash/bin)。在上面的示例中, //testapp:app是一种工具 show_app_outputtools 属性。 因此,其输出文件 app 会写入到 bazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app。 因此,执行路径为 bazel-out/cpu-opt-exec-hash/bin/testapp/app。这个额外的前缀 例如,为同一个项目中的两个不同的 CPU 构建相同的目标, 相同的 build,而不会产生相互影响。

    传递给此变量的标签必须恰好代表一个文件。对于 代表源文件的标签,则会自动设为 true。对于标签 表示规则,规则必须只生成一个输出。如果这是 false 或标签格式错误,则构建会失败并报错。

  • rootpath:表示已构建的二进制文件可用于 在运行时查找某个依赖项(相对于其 runfile 的子目录) 与主代码库对应的目录 注意:这仅适用于 --enable_runfiles已启用,但 默认为 Windows。请改用 rlocationpath: 跨平台支持。

    它与 execpath 类似,但去除了配置。 前缀。在上面的示例中,这意味着 empty.sourceapp 使用纯工作区相对路径 路径:testapp/empty.sourcetestapp/app

    外部代码库中文件的 rootpath repo 开头为 ../repo/,后跟 代码库相对路径。

    这同样是“只有一个输出”为 execpath

  • rlocationpath:构建的二进制文件可以传递给 runfiles 库的 Rlocation 函数的路径,以在以下位置查找依赖项 均可在 runfiles 目录(如果可用)中或使用 runfiles 清单

    它与 rootpath 类似,因为它不包含 不同配置前缀,但区别在于始终以 代码库的名称在上面的示例中,这意味着 empty.sourceapp 会导致以下结果: 路径:myproject/testapp/empty.source myproject/testapp/app

    外部代码库中文件的 rlocationpath repo 开头为 repo/,后跟 代码库相对路径。

    将此路径传递给二进制文件并使用以下命令将其解析为文件系统路径: 在 运行时。与 rootpath 相比,它具有以下优势: 适用于所有平台,即使 runfiles 目录 可用。

    这同样是“只有一个输出”为 execpath

  • locationexecpathrootpath,具体取决于要展开的属性。这是 除非您非常了解 Starlark 之前的旧版行为,否则我们不推荐 对特定规则执行的操作请参阅 #2475 了解详情。

execpathsrootpathsrlocationpaths、 和 locationsexecpath 的复数形式, rootpathrlocationpathslocation: 。它们支持生成多个输出的标签,在这种情况下 并用空格分隔每个输出。零输出规则和格式错误 标签会产生生成错误。

所有引用的标签必须显示在使用方目标的 srcs 中, 输出文件或 deps。否则,构建会失败。C++ 目标 还引用了 data 中的标签。

标签不必采用规范形式:foo:foo//somepkg:foo一切正常。

自定义变量

自定义“品牌”变量可以由任何标记为 “取决于‘创建变量’替换”,但仅限于 依赖于定义这些变量的其他目标。

最佳做法是所有变量都应该是自定义的,除非有非常好的变量 将它们融入核心 Bazel 的理由。这样就无需加载 为使用 taret 的变量提供可能代价高昂的依赖项 完全不在乎

C++ 工具链变量

以下内容在 C++ 工具链规则中定义,并且可用于任何规则 设置为 toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"] 有些规则(如 java_binary)会隐式 将 C++ 工具链添加到其规则定义中。它们会继承这些变量 。

内置的 C++ 规则比“在 C++ 上运行编译器 它”。为了支持 *SAN、ThinLTO、 并同时对二进制文件进行精心优化 在多个平台上快速运行测试,内置规则也适用, 长度,以确保设置正确的输入、输出和命令行标志 可能会包含多项内部生成的操作。

这些变量是语言专家在 在极少数情况下如果您想使用它们,请先与 Bazel 开发者联系

  • ABI:C++ ABI 版本。
  • AR:“ar”执行此命令
  • C_COMPILER: C/C++ 编译器标识符,例如llvm
  • CC:C 和 C++ 编译器命令。

    我们强烈建议您始终在CC_FLAGSCC的组合。否则,您需要自行承担风险。

  • CC_FLAGS:C/C++ 的最小标志集 可供 Genrule 使用的编译器。具体来说,这包含用于 如果 CC 支持多个 架构。
  • NM:“nm”执行此命令
  • OBJCOPY:来自与 C/C++ 相同的套件中的 objcopy 命令 。
  • STRIP:与 C/C++ 相同的套件中的 trip 命令 。

Java 工具链变量

以下内容在 Java 工具链规则中定义,并且可用于任何规则 设置 toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"](或 "@bazel_tools//tools/jdk:current_host_java_runtime" (针对主机工具链等效项)。

JDK 中的大多数工具不应直接使用。内置的 Java 规则使用更复杂的方法来进行 Java 编译和打包 与上游工具能够表达的程度相比,如 Jars 接口、标头接口 Jars 以及经过高度优化的 Jar 打包和合并实现。

这些变量是语言专家在 在极少数情况下如果您想使用它们,请先与 Bazel 开发者联系

  • JAVA:“java”命令(Java 虚拟机 )。请避免这种情况,并使用 java_binary 规则 。可以是相对路径。如果必须更改 在调用 java 之前,您需要捕获 然后再更改工作目录
  • JAVABASE:包含 Java 实用程序。可以是相对路径。它有一个“分箱” 子目录。

Starlark 定义的变量

规则和工具链写入者可以定义 完全自定义变量 TemplateVariableInfo 提供商。任何依赖于此类规则的规则 然后,toolchains 属性可以读取它们的值:

请查看 Starlark 定义的变量示例