build 配置是一组设置,例如 cpu = "arm64"
,其中
每项设置都会向已知的设备分配一个“配置值”
配置变量。这些值会影响
构建应用。
build 配置可被视为不可变字典映射变量 名称(字符串键)映射到配置值(布尔值、整数、字符串、列表) 字符串、标签或标签列表)。
它们仅在 Bazel 分析阶段才有意义, 其内容的唯一哈希值来表示。它们没有标签 不能直接出现在 Bazel 构建文件或 Starlark 代码中。
每个构建配置实例在 Bazel 下有自己的输出目录
output_base
,即:
${output_base}/execroot/<workspace_name>/bazel-out/<config_dir>/bin/
在 build 上下文中评估的目标的 build 工件
会存储在其中<config_dir>
值取决于内容
build 配置的一个子元素它的计算是一个 Bazel 实现细节,
在不同 Bazel 版本之间可能会存在差异
在最简单的情况下,<config_dir>
应如下所示:
${cpu}-${compilation_mode}
,例如 k8-fastbuild
1 或 aarch64-dbg
,
但很容易变得复杂得多。
小型 build 配置的一些示例 config_dir
值
但非常重要的示例 Bazel 项目:
k8-fastbuild
k8-fastbuild-ST-6f89e1bee3ea
k8-fastbuild-ST-bd2abcc18995
k8-fastbuild-ST-ec22d3eeb595
k8-opt
k8-opt-exec-2B5CBBC6
k8-opt-exec-2B5CBBC6-ST-5934bb4653e4
请注意,上面的十六进制值与配置的不相关 ID(即其唯一的哈希值)。
通用 build 配置
默认情况下,Bazel 管理两种配置:
默认配置,亦称为 目标配置,因为它对应于 它会针对最终的“目标”部分运行,系统。
默认情况下,其设置会与主机系统匹配,但可通过 命令行选项(见下文)。
主机配置,对应于必须在 运行 Bazel 的机器其中包含与默认设置相同的设置 配置除外,交叉编译(例如使用
--cpu=<name>
)时除外。
此外,还有:
- exec 配置,对应于在构建期间运行的代码 操作。实际上,这个文件包含与主机相同的设置 除非使用远程构建器时
Bazel 项目还可以定义额外配置,以满足某些 用例,例如针对多个目标架构交叉编译 构建一次代码
原生配置变量
bazel build
命令支持许多命令行选项,
更改原生配置变量(也称为原生 设置),
示例:
--cpu=<name>
和--host_cpu=<name>
:更改为默认值或主机生成的代码的 CPU 架构 配置。例如:
bazel build --cpu=arm64 --host_cpu=x86_64 ...
-c <mode>
、--compilation_mode=<mode>
或--host_compilation_mode=<mode>
:其中,
<mode>
是“fastbuild
”“dbg
”之一或“opt
”,用于描述 一组编译器链接器标记。例如:bazel build -c opt --host_compilation_mode=dbg ...
--crosstool=<file_path>
或--host_crosstool=<file_path>
:指向用于向 Bazel 描述自定义 C++ 工具链的
CROSSTOOL
文件。 用于编译和链接目标或主机二进制文件。
存在大量的原生配置变量(以及相关的 命令行标志)。例如,Bazel 5.2.0 支持超过 340 种 (包括 83 个实验性 API)。
自定义配置标志(已弃用)
您可以定义自定义配置变量(名称混淆)
自定义配置标志,这些标志将在
命令行中的“--define <name>=<value>
”,其中 <name>
是
任意 build 配置变量名称,并且 <value>
会记录为
任意字符串(一律不对该值进行解释)。
您可以使用特殊的结构在 BUILD.bazel
文件中测试这些名称,
例如:
# This represents a named configuration condition which will be True whenever
# `--define foo=bar` is used in the `bazel build` command-line.
config_setting(
name = "is_foo_bar",
define_flags = {
"foo": "bar",
}
)
用户定义的构建设置
为了克服自定义 --define
标志的限制,Bazel 项目可以
现在定义 build 配置变量,以便:
使用标签命名(提供工作区和软件包范围, 以及可用性检查)。
可以是特定类型,可以是以下之一:布尔值、整数、字符串、字符串列表、 标签和标签列表。
始终提供默认值。
只需在命令行中使用“--<label>=<value>
”即可进行设置如:
# Set the build setting named enable_logs defined in # $WORKSPACE/my_settings/BUILD.bazel to True. # # Note that the double-slash must follow the double caret directly # without spaces between them.
bazel build --//my_settings:enable_logs=True …
与必须出现在文件中的定义匹配
$PROJECT/my_settings/BUILD.bazel
,例如:
# From my_settings/BUILD.bazel
load("@bazel_skylib//rules/common_settings.bzl", "bool_flag")
bool_flag(
name = "enable_logs",
default_value = False
)
构建设置也可以在外部代码库中定义,如下所示:
# Set the build setting named enable_logs defined in the config/BUILD.bazel # file of the @project_settings external repository.
bazel build --@project_settings//config:enable_logs=True …
存储用户配置值
不要直接在命令行上传递它们,
可将配置值存储在 .bazelrc
文件中,该文件位于
在项目工作区目录的顶部,如:
# from $PROJECT/.bazelrc
build --host_copt=-O3 -s
build --copt=-O1 -g -Wall
build --//my_settings:enable_logs=True
调用 bazel build <target>
时,.bazelrc
提供的选项
会自动包含在内,从而生成等效的命令
更改为:
bazel build --host_copy="-O3 -s" --copt="-O1 -g -Wall" --//my_settings:enable_logs=True <target>
您还可以使用自定义 name 对多个定义进行分组,如下所示:
# from $PROJECT/.bazelrc
build:conf_x64 --cpu=x86_64
build:conf_x64 --copt=-mavx2
build:conf_arm64 --cpu=aarch64
build:conf_arm64 --copt=-marmv8.1-a+simd
然后使用 --config=<name>
从一个组中选择所有选项,如下所示:
bazel build --config=conf_x64 <target>
这相当于:
bazel build --cpu=x86_64 --copt=-mavx2 <target>
您也可以将 --config
与其他选项结合使用,如下所示:
bazel build --config=conf_arm64 --copy="-DENABLE_ASSERTS=1" ...
===
重要提示:尽管名称如此,--config
选项并不会创建新的
build 配置。这只是一种对命令行进行分组的便捷方式
提供不同的选项每个 <name>
只是以递归方式展开为
然后被 Bazel 完全忽略。
配置转换(快速概览)
除了标准目标、主机和执行配置之外,Bazel 还支持 使用“过渡”的概念创建额外的 build 配置。
转场是一种高级功能,本文不做详细介绍, 需要注意的是:
build 配置从概念上来说只是 映射到配置值E.g.:
{ "copt": "-O2 -g", "cpu": "x86_64", "compiler": "gcc", "//my_settings:enable_logs": True, … }
过渡提供了一个函数,该函数采用“当前 build 配置” 作为输入,并返回新的构建配置作为输出。
转换函数只能修改字典中的值,即 它无法在输入中添加或移除键。
转换函数在分析阶段调用(稍后介绍), 且无法由用户直接触发 命令行或
.bazelrc
文件。
检查 build 配置
运行 Bazel 构建命令后,您可以查看
所需的资源使用 bazel config
命令输出所有
配置及其 config_dir
值,例如:
$ bazel clean
$ bazel build //src:program
$ bazel config
Available configurations:
20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2 k8-fastbuild
30f5a27e1bd054836d97b800bdfe61c6d1cffccdf6b82c9963e94020e3852026 k8-fastbuild-ST-bd2abcc18995
34e198ac81dafe34b82cf62466cc84f5b1af6ef8dce44b9283b3152a6635f64a k8-fastbuild-ST-6f89e1bee3ea
aaa26904110821b8e0f87aabfffcfb8e5003a5620aee74de3d7ddea9a654c0f6 k8-opt (host)
d6b1a93e6619d845f29ee752e338ec2636e7fbf4c88e50168602cc21f5ae6f13 k8-opt-exec-2B5CBBC6-ST-5934bb4653e4 (exec)
注意:配置信息会累积,直到下一次清除 bazel。
使用 bazel config <id>
将配置转储到 stdout,以检查其
值。警告:输出很长。
$ bazel config 20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2 | wc -l
Loading:
INFO: Displaying config with id 20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2
436
此处为实际输出的链接。
请注意,在实践中,每个配置都是一组字典,每个字典 特定主题。这些称为 fragment,而 只有几个可以直接从 Starlark 访问:
$ bazel config 20222e2616387f00ae3814d79f82a650829d1aea962d558edda5cf54c459f4a2 | grep FragmentOptions
FragmentOptions com.google.devtools.build.lib.analysis.PlatformOptions {
FragmentOptions com.google.devtools.build.lib.analysis.ShellConfiguration$Options {
FragmentOptions com.google.devtools.build.lib.analysis.config.CoreOptions {
FragmentOptions com.google.devtools.build.lib.analysis.test.CoverageConfiguration$CoverageOptions {
FragmentOptions com.google.devtools.build.lib.analysis.test.TestConfiguration$TestOptions {
FragmentOptions com.google.devtools.build.lib.bazel.rules.BazelRuleClassProvider$StrictActionEnvOptions {
FragmentOptions com.google.devtools.build.lib.bazel.rules.python.BazelPythonConfiguration$Options {
FragmentOptions com.google.devtools.build.lib.rules.android.AndroidConfiguration$Options {