Bazel 将COPT/defines传播到所有目标';s依赖关系

Bazel 将COPT/defines传播到所有目标';s依赖关系,bazel,Bazel,我有一个项目,在一个相当复杂的构建系统中,在一个工作区中涉及多个构建文件。简而言之,我的目标是:对于某些特定的目标,我希望它的所有递归依赖项都使用一组额外的属性(copts/defines)来构建,而不是以任何其他方式构建这些依赖项目标。我还没有找到一个干净的方法 例如,目标G通常使用copts=[]构建。如果目标P依赖于目标G,并且我运行bazel build:P,那么我希望两个目标都使用copts=[“-DMY\u DEFINE”]以及目标G的所有依赖项来构建,等等 该参数以相反的方向传播:

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

例如,目标G通常使用
copts=[]
构建。如果目标P依赖于目标G,并且我运行
bazel build:P
,那么我希望两个目标都使用
copts=[“-DMY\u DEFINE”]
以及目标G的所有依赖项来构建,等等

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

限制:

  • 为了避免自定义命令行标志,我不控制人们如何调用
    bazel{build,test}
  • 复制整个依赖关系目标树是不实际的
似乎无法从生成文件或目标中设置
config\u设置的值,因此基于
select
的解决方案似乎无法工作

以前的工作:

  • -2017,推荐“平行树”或自定义宏(其中我们已经有很多,将它们包装到另一个宏中会很困难)
  • -我相信这些都依赖于自定义命令行标志
创建一个不需要命令行标志。如果设置了
flag=False
,则实际上无法在命令行上设置它。您可以使用a来设置它

我想这样的东西可以满足你的需要(保存在
extra\u copts.bzl
):

def\u extra\u copts\u impl(ctx):
context=cc\u common.create\u compilation\u context(
defines=depset(ctx.build\u设置\u值)
)
返回[CcInfo(编译上下文=上下文)]
额外条款=规则(
实施=_extra_copts_impl,
build\u setting=config.string\u list(flag=False),
)
定义使用额外的copts实施(ctx):
返回[ctx.attr.\u copts[CcInfo]]
使用额外的copts=规则(
实现=\u使用\u额外\u copts\u实现,
attrs=“\u copts”:attr.label(默认=“/:extra\u copts”)},
)
定义添加copts impl(设置、属性):
返回{”//:extra_copts:[“MY_DEFINE”]}
_add_copts=转换(
实施=_add_copts_impl,
输入=[],
输出=[“/:额外的”],
)
具有额外copts实施(ctx)的def:
infos=[d[CcInfo]表示ctx.attr.deps中的d]
返回[cc_common.merge_cc_infos(cc_infos=infos)]
带额外的copts=规则(
实现=\u与\u额外\u copts\u实现,
属性={
“部门”:属性标签列表(cfg=\u添加\u copts),
“\u allowlist\u function\u transition”:属性标签(
default=“@bazel\u tools//tools/allowlist/function\u transition\u allowlist”
)
},
)
然后在
BUILD
文件中:

load(“/:extra\u copts.bzl”、“extra\u copts”、“use\u extra\u copts”、“with\u extra\u copts”)
extra\u copts(name=“extra\u copts”,构建设置\u默认值=[])
使用额外股份(name=“使用额外股份”)
图书馆(
name=“G”,
deps=[“:使用额外的copts”],
)
有额外的COPT(
name=“P_deps”,
deps=[“:G”],
)
图书馆(
name=“P”,
deps=[“:P_deps”],
)
extra_copts
是构建设置。它直接返回,这意味着用相同的方法进行任何其他C++库交换是很简单的。它的默认值实际上是一个“空的”
CcInfo
,它不会对依赖它的库做任何事情

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

\u add\u copts
与\u extra\u copts
的转换,用于更改
extra\u copts
构建设置的值。它可以检查
attr
,做一些比添加硬编码列表更复杂的事情

use\u extra\u copts
extra\u copts
中提取
CcInfo
,以便
cc\u库可以使用它们

<>避免重写构建C++规则,使用包装规则来撤出COPT并进行转换。您可能希望创建宏,将包装器规则与相应的cc_库捆绑在一起。或者,您可以使用一个起点来创建自定义规则,该规则重用构建规则C++的核心实现,同时将生成设置的转换和使用集成到一个规则中。