假设我有一个库实现,我只想在用户在构建时指定它时编译。
我应该使用features
标志吗?
如果是这样,我如何使用功能标志来约束编译,就像您在cc_library
,cc_test
和cc_binary
中使用target_compatible_with
一样?
如果不是,约束它的最好方法是什么?调整platforms
标志会干扰默认平台检测。
听起来您想要一个用户定义的构建设置,它是一个命令行标志。最简单的方法是使用常见的构建设置规则之一,并在构建文件中实例化它(在本例中称为flags/BUILD
):
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
bool_flag(
name = "flag",
build_setting_default = False,
visibility = ["//visibility:public"],
)
然后您可以使用--//flags:flag
从命令行设置它。如果你想要一个不那么丑陋的语法,构建设置别名也可用。
一旦你有了可以触发config_setting的东西,创建一个可选的库就很简单了。首先,当没有设置标志时,要禁用库本身:
config_setting(
name = "have_flag",
flag_values = {
"//flags:flag": "true",
},
)
cc_library(
name = "sometimes",
target_compatible_with = select({
":have_flag": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
)
任何标记为需要@platforms//:incompatible
的东西都不会与任何真正的平台兼容,所以当你没有bazel build //...
标志时,这将跳过库,使任何依赖它的东西都出错。
我猜您有其他目标,当启用时依赖于这个库,这可以类似地处理:
cc_binary(
name = "thing",
deps = [
"//:something_else",
] + select({
":have_flag": [":sometimes"],
"//conditions:default": [],
}),
)
如果你想定义一个预处理器宏来告诉依赖代码是否使用可选的依赖(或交换源文件,或更改链接选项等),那么你可以像使用copts
,defines
,srcs
和大多数其他cc_library
/cc_binary
属性一样使用select
。
利用标签manual
,例如:
cc_test(name = "my_test"
...
tags = ["manual"]
)