如何在Bazel中根据引用源配置全局头文件?
问题解答
你示例中的写法不可行。Bazel的select是基于构建配置条件(比如平台、编译模式、自定义config_setting)来做分支选择的,没办法直接根据“当前依赖的包”动态调整defines——同一个cc_library target在构建过程中只会有一套固定的编译参数,不会因为被不同包依赖而改变。
针对你的最终目标,这里提供几种可行的解决方案:
方案1:为A创建不同配置的变体Target
在A所在的BUILD文件中,为不同的配置需求创建独立的cc_library,分别设置对应的宏定义:
# A.BUILD cc_library( name = "A_foo", hdrs = ["global_config.h"], defines = ["-DFOO"], ) cc_library( name = "A_bar", hdrs = ["global_config.h"], defines = ["-DBAR"], )
然后让B和C分别依赖对应的变体:
# B.BUILD cc_library( name = "B", srcs = ["b_including_global_config.cpp"], deps = ["//some/path/to:A_foo"], )
# C.BUILD cc_library( name = "C", srcs = ["c_including_global_config.cpp"], deps = ["//some/path/to:A_bar"], )
这个方案逻辑清晰,每个变体的配置明确,适合依赖关系固定的场景。
方案2:让依赖包自行传递宏定义
将A简化为仅提供头文件的库,不设置任何宏定义,把宏定义的控制权交给引用它的B和C:
# A.BUILD cc_library( name = "A", hdrs = ["global_config.h"], )
在B和C的BUILD中添加各自需要的宏定义:
# B.BUILD cc_library( name = "B", srcs = ["b_including_global_config.cpp"], deps = ["//some/path/to:A"], defines = ["-DFOO"], )
# C.BUILD cc_library( name = "C", srcs = ["c_including_global_config.cpp"], deps = ["//some/path/to:A"], defines = ["-DBAR"], )
这种方式下,宏定义会作用于B/C自身的编译单元,只要它们的源文件引用global_config.h,就能触发对应的#ifdef分支。
方案3:通过构建参数全局切换配置(适合单场景切换)
如果需要通过命令行参数全局控制宏定义,可以自定义config_setting配合select:
首先在A所在包的BUILD中定义配置条件:
config_setting( name = "use_foo", define_values = {"config": "foo"}, ) config_setting( name = "use_bar", define_values = {"config": "bar"}, )
然后在A的cc_library中使用select:
cc_library( name = "A", hdrs = ["global_config.h"], defines = select({ ":use_foo": ["-DFOO"], ":use_bar": ["-DBAR"], "//conditions:default": [], }), )
构建时通过命令行参数切换配置:
# 构建B时启用FOO定义 bazel build //path/to:B --define=config=foo # 构建C时启用BAR定义 bazel build //path/to:C --define=config=bar
注意:这个方案是全局生效的,同一构建任务中只能选择一种配置,不适合同时构建B和C的场景。
内容的提问来源于stack exchange,提问作者cppbest
相关产品推荐
相关产品推荐

