提问人:cppbest 提问时间:11/2/2023 最后编辑:cppbest 更新时间:11/4/2023 访问量:84
如何根据 bazel 中包含的标头配置标头?
How to configure a header based on the sources that include it in bazel?
问:
我想要一个目标,该目标具有根据我所在的当前包而变化的属性。类似的东西:defines
A.构建:
cc_library(
name = "A",
hdrs = ["global_config.h"],
defines = select({
"???current package = B???": ["-DFOO"],
"???current package = C???": ["-DBAR"],
})
)
B.构建:
cc_library(
name = "B",
srcs = ["b_including_global_config.cpp"],
deps = ["//some/path/to/A.BUILD:A"], # we define -DFOO for B
)
C.构建:
cc_library(
name = "C",
srcs = ["c_including_global_config.cpp"],
deps = ["//some/path/to/A.BUILD:A"], # we define -DBAR for C
)
这在 bazel 中可能吗?
最终目标是拥有一个全局配置头文件,我可以根据包含它的源的位置对其进行配置 ()。因此,此处的 B 和 C 包含的源都包含来自 A 的一些公共标头,而来自 A 的这个标头包含 和 。也欢迎对原始问题进行任何其他解决方案。#ifdef FOO
#ifdef FOO
#ifdef BAR
答:
好吧,这(如前所述)不能在 bazel 中完成(或者我认为任何理智的构建系统),因为依赖项的提供者(再次通常)没有也不应该真正了解依赖于它的代码。在依赖关系图中拥有这种双向性首先会破坏单个包的目的。如果 A 和 B 在两个方向上都紧密耦合,它们实际上不应该是 A 和 B,而只是一个 X。我从“粒度”中获益甚微,而我却增加了设置的复杂性。
TBH 我会质疑配置的“全局性”,它基本上基于包含在单个(全局)文件中,但实际上仍然是在所述文件的不同部分维护的单独配置,并使用预处理器条件选择(例如这里)。
可是。。。如果你真的确定这个设计,我会说,在你的来源中描述一下。即在包含 .同样,在 .在这一点上,这些并不是真正独立的包(源)彼此不可知吗?你仍然可以在消费/包含点(这里和)这样做(这是另一罐蠕虫),但分散来源......好吧,来源和构建描述似乎又只是增加了复杂性/混乱,而没有明显的收益?b_including_global_config.cpp
#define FOO
global_config.h
#define BAR
c_including_global_config.cpp
copts
B
C
我很可能只留下全局/公共部分,并放入任何仅与 in 相关的东西和与 in 相关的内容。global_config.h
B
B
C
C
如果简化示例丢失了某种程度的重用,例如,假设三个使用者 B、C 和 D,其中 B 和 D 共享位,C 和 D 共享其他位。我可以有一个“真正的”,然后可能会有......我将有三个头文件(或一个有三个头文件)并依赖它们并相应地包含头文件。是的,它确实在 BUILD 配置/包源文件中添加了一行(或一些),但这(依赖项描述)主要是一次性成本。当我尝试阅读它并理解哪个部分的内容时,它确实使树更容易理解(顺便说一句,这就是为什么我通常也会谨慎使用,因为它可能很诱人,因为它可能很诱人)有一个“简洁”的构建描述)。global_config.h
shared_config_b_and_d.h
shared_config_c_and_d.h
cc_libraries
select()
评论