Rob*_*bie 4 c++ build bazel bazel-rules
假设我有一个库实现,我只想在用户在构建时指定它时进行编译。
我应该使用features标志吗?
如果是这样,我如何使用 features 标志来限制编译,就像target_compatible_within cc_library、cc_test和 一样cc_binary?
如果不是,限制这种情况的最佳方法是什么?调整platforms标志会干扰默认平台检测。
听起来您想要一个用户定义的构建设置,它是一个命令行标志。最简单的方法是使用常见的构建设置规则之一,并在 BUILD 文件中实例化它(flags/BUILD在本示例中调用它):
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag")
bool_flag(
name = "flag",
build_setting_default = False,
visibility = ["//visibility:public"],
)
Run Code Online (Sandbox Code Playgroud)
然后您可以使用命令行来设置它--//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"],
}),
)
Run Code Online (Sandbox Code Playgroud)
任何标记为需要的东西@platforms//:incompatible都永远不会与任何真实的平台兼容,因此当您bazel build //...没有该标志时,这将跳过该库,并使任何依赖它的东西成为错误。
我猜您在启用时还有其他依赖于该库的目标,可以类似地处理:
cc_binary(
name = "thing",
deps = [
"//:something_else",
] + select({
":have_flag": [":sometimes"],
"//conditions:default": [],
}),
)
Run Code Online (Sandbox Code Playgroud)
如果您想定义一个预处理器宏来告诉依赖代码是否使用可选依赖项(或交换源文件,或更改链接选项等),那么您可以select像这样使用copts、defines、srcs和大多数其他cc_library/cc_binary属性。