【发布时间】:2019-08-07 22:15:48
【问题描述】:
我试图在编译时根据用户是运行bazel test 还是bazel build 来提供一些预处理器定义。
具体来说,我想有一个cc_library.deps 的条件依赖和cc_library.defines 中的条件定义。
我发现select() 是可行的方法,但我不知道如何知道用户执行了什么操作。
【问题讨论】:
标签: bazel
我试图在编译时根据用户是运行bazel test 还是bazel build 来提供一些预处理器定义。
具体来说,我想有一个cc_library.deps 的条件依赖和cc_library.defines 中的条件定义。
我发现select() 是可行的方法,但我不知道如何知道用户执行了什么操作。
【问题讨论】:
标签: bazel
我不知道使用 select() 检测当前命令(build 与 test)的任何方法,但我认为您可以使用 custom keys 实现类似的效果。
您可以定义一个config_setting 块,如下所示:
# BUILD
config_setting(
name = "custom",
values = {
"define": "enable_my_flag=true"
}
)
并在你的库中使用它来控制defines:
# BUILD - continued
cc_library(
name = "mylib",
hdrs = ["mylib.h"],
srcs = ["mylib.cc"],
defines = select({
":custom": ["MY_FLAG"],
"//conditions:default": [],
})
)
现在使用 bazel build :mylib 构建库将导致默认情况 - 不存在定义,但如果您使用 bazel build :mylib --define enable_my_flag=true 构建,则将选择另一个分支并定义 MY_FLAG。
这可以很容易地扩展到测试用例,例如通过将--define 添加到您的.bazelrc:
# .bazelrc
test --define enable_my_flag=true
现在每次运行 bazel test :mylib_test 时,都会附加 define 标志,并且将使用定义的 MY_FLAG 构建库。
出于好奇,您为什么要在使用一组不同的定义/依赖项构建的库上运行测试?这可能会破坏测试的目的,因为最终您要测试的东西与您要使用的库不同。
【讨论】:
custom,但它并没有出现在命令行的任何地方。而它的定义是建立一个键值对映射define到enable_my_flag=true。目前尚不清楚define 是否是一个bazel 概念,或者它如何暴露#define 的C 概念。但是由于某种原因,我们用于设置的键是我们放在命令行上的......我们将它设置为一个看起来像设置变量的字符串值,但我猜只是一个字符串?