我正在尝试使用 bazel 有条件地编译 C++ 库,具体取决于在构建/运行使用该库的目标之一或库本身时是否设置了特定标志。
我的图书馆有这样的东西:
//libraryheader.hpp
#ifdef MY_MACRO
#pragma message("MY_MACRO is defined")
//do something
#else
// do something else
#endif
这是我尝试过的。 BUILD 文件看起来像这样
#BUILD
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
use_the_feature_macro = string_flag(
name = "use_the_feature",
build_setting_default = "",
)
cc_library(
name = "my_library",
testonly = True,
srcs = [
"somefile.cpp",
],
hdrs = [
"libraryheader.hpp",
],
copts = select({
":use_the_feature_macro": ["-DMY_MACRO"],
"//conditions:default": [],
}),
data = [],
visibility = ["//path/to/smth:__subpackages__"],
deps = [
"//path/to/smth:targ1",
...
],
)
当尝试使用像
bazel build --use_the_feature //path/to:my_library
这样的命令进行构建时,我不断收到有关无法识别的选项的错误。我也尝试过使用 `bazel build --//path/to:use_feature //path/to:my_library 但它不起作用。仍然无法识别的选项
错误:--use_the_feature :: 无法识别的选项:--use_the_feature
我希望实现的是能够在单独编译库时或编译使用该库的目标时有条件地编译该库。目前,查看 bazel 文档,我不知道是否应该使用 string_flag 还是 config_setting,而且他们 github 上的示例非常难以理解。
对于初学者,如果您所需要做的只是切换启用/禁用状态,您可能需要使用
bool_flag
而不是 string_flag
。
config_setting
,然后您可以在您的select()
中使用它。
这是一个完整的工作示例:
load("@bazel_skylib//rules:common_settings.bzl", "string_flag")
config_setting(
name = "feature_is_used",
flag_values = {
":use_the_feature": "yes",
},
)
use_the_feature_macro = string_flag(
name = "use_the_feature",
build_setting_default = "",
)
cc_library(
name = "my_library",
testonly = True,
srcs = ["somefile.cpp"],
hdrs = ["libraryheader.hpp"],
copts = select({
":feature_is_used": ["-DMY_MACRO"],
"//conditions:default": [],
}),
)
如果您想要单个切换,可以使用
bazel build --//:use_the_feature=yes :my_library" to build with the macro. There's nothing special about the word "yes", you can enable macros one-by-one this way, or you can switch to using a
bool_flag`。
为了完整起见,以下是构建所需的其余文件:
MODULE.bazel
bazel_dep(name = "bazel_skylib", version = "1.5.0")
libraryheader.hpp
// libraryheader.hpp
#ifdef MY_MACRO
#pragma message("MY_MACRO is defined")
// do something
#else
// do something else
#endif