gpt4 book ai didi

bazel - 将 copts/defines 传播到目标的所有依赖项

转载 作者:行者123 更新时间:2023-12-05 04:54:12 27 4
gpt4 key购买 nike

我有一个项目在一个相当复杂的构建系统中,在一个工作空间中涉及多个构建文件。我的目标简而言之:对于某些特定的目标,我希望它的所有递归依赖项都使用一组额外的属性(copts/defines)来构建,而不是那些依赖项目标以任何其他方式构建。我还没有找到一种干净利落的方法。

例如,目标 G 通常使用 copts = [] 构建。如果目标 P 依赖于目标 G,并且我运行 bazel build :P,我希望两个目标都使用 copts = ["-DMY_DEFINE"] 构建,连同所有目标G等的依赖

cc_binary.defines参数以相反方向传播:所有依赖于某个目标 A 的目标都将接收目标 A 的所有 define

限制:

  • 更喜欢避免自定义命令行标志,我不控制人们如何调用 bazel {build,test}
  • 复制整个依赖目标树是不切实际的

从 BUILD 文件或目标中设置 config_setting 的值似乎是不可能的,因此基于 select 的解决方案似乎不能工作。

以前的工作:

最佳答案

创建 user-defined build setting不需要命令行标志。如果你设置flag = False,那么它实际上不能在命令行上设置。您可以使用 user-defined transition改为设置它。

我认为像这样的东西可以满足您的需求(保存在 extra_copts.bzl 中):

def _extra_copts_impl(ctx):
context = cc_common.create_compilation_context(
defines = depset(ctx.build_setting_value)
)
return [CcInfo(compilation_context = context)]

extra_copts = rule(
implementation = _extra_copts_impl,
build_setting = config.string_list(flag = False),
)

def _use_extra_copts_implementation(ctx):
return [ctx.attr._copts[CcInfo]]

use_extra_copts = rule(
implementation = _use_extra_copts_implementation,
attrs = "_copts": attr.label(default = "//:extra_copts")},
)

def _add_copts_impl(settings, attr):
return {"//:extra_copts": ["MY_DEFINE"]}

_add_copts = transition(
implementation = _add_copts_impl,
inputs = [],
outputs = ["//:extra_copts"],
)

def _with_extra_copts_implementation(ctx):
infos = [d[CcInfo] for d in ctx.attr.deps]
return [cc_common.merge_cc_infos(cc_infos = infos)]

with_extra_copts = rule(
implementation = _with_extra_copts_implementation,
attrs = {
"deps": attr.label_list(cfg = _add_copts),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist"
)
},
)

然后在 BUILD 文件中:

load("//:extra_copts.bzl", "extra_copts", "use_extra_copts", "with_extra_copts")

extra_copts(name = "extra_copts", build_setting_default = [])

use_extra_copts(name = "use_extra_copts")

cc_library(
name = "G",
deps = [":use_extra_copts"],
)

with_extra_copts(
name = "P_deps",
deps = [":G"],
)

cc_library(
name = "P",
deps = [":P_deps"],
)

extra_copts 是build设置。它返回 CcInfo直接,这意味着使用相同的方法可以直接交换任何其他 C++ 库。它的默认值实际上是一个“空的”CcInfo,它不会对依赖它的库做任何事情。

with_extra_copts 包装了一组依赖项,配置为使用不同的 CcInfo。这是实际更改值的规则,以创建具有不同标志的 G 的第二个版本。

_add_coptswith_extra_copts 用于更改 extra_copts build设置值的转换。它可以检查 attr 来做一些比添加硬编码列表更复杂的事情。

use_extra_coptsextra_copts 中提取 CcInfo,以便 cc_library 可以使用它们。

为了避免重写内置的 C++ 规则,它使用包装器规则来拉出 copts 并进行转换。您可能想要创建宏来将包装器规则与相应的 cc_library 捆绑在一起。或者,您可以使用 rules_cc's my_c_archive作为创建自定义规则的起点,这些规则重用内置 C++ 规则的核心实现,同时将build设置的转换和使用集成到单个规则中。

关于bazel - 将 copts/defines 传播到目标的所有依赖项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65837131/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com