什么是正确的方式来选择性地编译一个库与构建标志(放置在' target_compatible_with ')?<



假设我有一个库实现,我只想在用户在构建时指定它时编译。

我应该使用features标志吗?

如果是这样,我如何使用功能标志来约束编译,就像您在cc_library,cc_testcc_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"]
)

最新更新