如何根据 bazel 中包含的标头配置标头?

How to configure a header based on the sources that include it in bazel?

提问人:cppbest 提问时间:11/2/2023 最后编辑:cppbest 更新时间:11/4/2023 访问量:84

问:

我想要一个目标,该目标具有根据我所在的当前包而变化的属性。类似的东西: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

C++ 构建 C-preprocessor bazel-rules

评论


答:

1赞 Ondrej K. 11/4/2023 #1

好吧,这(如前所述)不能在 bazel 中完成(或者我认为任何理智的构建系统),因为依赖项的提供者(再次通常)没有也不应该真正了解依赖于它的代码。在依赖关系图中拥有这种双向性首先会破坏单个包的目的。如果 A 和 B 在两个方向上都紧密耦合,它们实际上不应该是 A 和 B,而只是一个 X。我从“粒度”中获益甚微,而我却增加了设置的复杂性。

TBH 我会质疑配置的“全局性”,它基本上基于包含在单个(全局)文件中,但实际上仍然是在所述文件的不同部分维护的单独配置,并使用预处理器条件选择(例如这里)。

可是。。。如果你真的确定这个设计,我会说,在你的来源中描述一下。即在包含 .同样,在 .在这一点上,这些并不是真正独立的包(源)彼此不可知吗?你仍然可以在消费/包含点(这里和)这样做(这是另一罐蠕虫),但分散来源......好吧,来源和构建描述似乎又只是增加了复杂性/混乱,而没有明显的收益?b_including_global_config.cpp#define FOOglobal_config.h#define BARc_including_global_config.cppcoptsBC

我很可能只留下全局/公共部分,并放入任何仅与 in 相关的东西和与 in 相关的内容。global_config.hBBCC

如果简化示例丢失了某种程度的重用,例如,假设三个使用者 B、C 和 D,其中 B 和 D 共享位,C 和 D 共享其他位。我可以有一个“真正的”,然后可能会有......我将有三个头文件(或一个有三个头文件)并依赖它们并相应地包含头文件。是的,它确实在 BUILD 配置/包源文件中添加了一行(或一些),但这(依赖项描述)主要是一次性成本。当我尝试阅读它并理解哪个部分的内容时,它确实使树更容易理解(顺便说一句,这就是为什么我通常也会谨慎使用,因为它可能很诱人,因为它可能很诱人)有一个“简洁”的构建描述)。global_config.hshared_config_b_and_d.hshared_config_c_and_d.hcc_librariesselect()