我想要一个具有这样的
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中可能吗?
最终目标是拥有一个全局配置头文件,我可以根据包含它的源的位置进行配置(
#ifdef FOO
)。因此,这里的 B 和 C 包含的源都包含来自 A 的一些公共标头,并且来自 A 的这个标头包含 #ifdef FOO
和 #ifdef BAR
。也欢迎对原始问题的任何其他解决方案。
好吧,(如上所述)不能在 bazel (或者我认为任何健全的构建系统)中完成,因为依赖项的提供者(同样通常)不也不应该真正了解依赖于的代码它。在依赖关系图中具有这种双向性首先会破坏单个包的目的。如果 A 和 B 在两个方向上紧密耦合,那么它们实际上不应该是 A 和 B,而只是一个 X。我从“粒度”中获益甚少,同时增加了设置的复杂性。
TBH 我会质疑基本上基于包含在单个(全局)文件中的配置的“全局性”,但实际上仍然是在所述文件的不同部分中维护的单独配置,并使用预处理器条件进行选择(例如此处)。
也就是说......如果您真的对设计很有把握,我会说,请在您的来源中进行描述。 IE。有
b_including_global_config.cpp
:#define FOO
在包含 global_config.h
之前。同样,在 #define BAR
中执行 c_including_global_config.cpp
。在这一点上,这些并不是真正独立的包(来源),彼此不可知?您仍然可以在消费/包含点(此处为 copts
和 B
)以 C
(这是另一种蠕虫)的方式做到这一点,但是将源分散在......井源和构建描述中再次似乎主要只是增加复杂性/混乱而没有明显的收获?
我很可能只在
global_config.h
中留下全局/公共部分,并将仅与 B
相关的内容放入 B
中,将与 C
相关的内容放入 C
中。
如果简化示例失去了一定程度的重用性,例如我们假设三个消费者 B、C 和 D,其中 B 和 D 共享位,而 C 和 D 共享其他位。我可以有一个“真正的”
global_config.h
,然后可能有shared_config_b_and_d.h
和shared_config_c_and_d.h
...我将有三个标头cc_libraries
(或一个具有三个头文件)并依赖它们并相应地包含头文件。是的,它确实向 BUILD 配置/包源文件添加了一行(或一些行),但这(依赖项的描述)主要是一次性成本。当我尝试阅读它并理解哪个部分包含什么内容时,它确实使这棵树更容易理解(顺便说一句,这就是为什么我通常也会谨慎地使用 select()
,因为它可能具有“简洁”的诱惑)构建描述)。