You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何构建foo3时Bazel规则仅生成foo3文件而非预期三个文件?

问题

我编写了用于增量测试的Bazel规则foo_binary,规则逻辑如下:

  • 无依赖时,生成以自身名称命名的文件,内容为自身名称;
  • 存在依赖时,生成以自身名称命名的文件,内容为依赖目标生成文件的内容加上自身名称。

测试时,foo3、foo2、foo1构成依赖链,构建foo3时预期生成foo1、foo2、foo3三个文件,但实际仅生成了foo3文件。

以下是测试用Bazel代码、构建命令及日志:

规则实现代码

# ~/rules/dev.bzl
def _foo_binary_impl(ctx):

    this_name = ctx.attr.name
    file_name = ctx.actions.declare_file(ctx.label.name)

    print("##-000 this_name: {}".format(this_name))
    print("##-001 file_name: {}".format(file_name))

    file_content = ""

    if ctx.attr.deps:
        for dep in ctx.attr.deps:
            t1 = dep[DefaultInfo].files.to_list()[0].basename
            t1 = t1 + this_name
            print("##-100 t1: {}".format(t1))

            file_content = t1

    else:
        t2 = this_name
        print("##-101 t2: {}".format(t2))

        file_content = t2

    ctx.actions.write(
        output = file_name,
        content = file_content,
    )

    return [
        DefaultInfo(
            files = depset([file_name])
        ),
    ]

foo_binary = rule(
    implementation = _foo_binary_impl,
    attrs = {
        "deps": attr.label_list(),
    },
)

构建命令及日志

$> bazel build -s //rules/example:foo3                                                                                                                                                                           1 х  11:38:08 
DEBUG: ~/rules/dev.bzl:10:10: ##-000 this_name: foo1
DEBUG: ~/rules/dev.bzl:11:10: ##-001 file_name: <generated file rules/example/foo1>
DEBUG: ~/rules/dev.bzl:25:14: ##-101 t2: foo1
DEBUG: ~/rules/dev.bzl:10:10: ##-000 this_name: foo2
DEBUG: ~/rules/dev.bzl:11:10: ##-001 file_name: <generated file rules/example/foo2>
DEBUG: ~/rules/dev.bzl:19:18: ##-100 t1: foo1foo2
DEBUG: ~/rules/dev.bzl:10:10: ##-000 this_name: foo3
DEBUG: ~/rules/dev.bzl:11:10: ##-001 file_name: <generated file rules/example/foo3>
DEBUG: ~/rules/dev.bzl:19:18: ##-100 t1: foo2foo3
INFO: Analyzed target //rules/example:foo3 (3 packages loaded, 8 targets configured).
INFO: Found 1 target...
Target //rules/example:foo3 up-to-date:
  bazel-bin/rules/example/foo3
INFO: Elapsed time: 0.107s, Critical Path: 0.00s
INFO: 2 processes: 2 internal.
INFO: Build completed successfully, 2 total actions
问题原因及解决方案

核心问题

  1. Bazel输出机制限制:Bazel默认仅输出构建目标直接关联的产物,依赖目标的产物不会自动被复制到输出目录。日志中能看到foo1、foo2的逻辑已执行,但它们的产物属于依赖目标的输出,不会被包含在foo3的输出结果里。
  2. 内容读取逻辑错误:当前代码仅取了依赖文件的basename(文件名),而非文件的实际内容,不符合你预期的“依赖目标生成文件的内容加上自身名称”逻辑。

修复代码

# ~/rules/dev.bzl
def _foo_binary_impl(ctx):

    this_name = ctx.attr.name
    file_name = ctx.actions.declare_file(ctx.label.name)

    print("##-000 this_name: {}".format(this_name))
    print("##-001 file_name: {}".format(file_name))

    file_content = ""

    if ctx.attr.deps:
        dep_contents = []
        for dep in ctx.attr.deps:
            dep_file = dep[DefaultInfo].files.to_list()[0]
            # 读取依赖文件的实际内容,Bazel会自动处理依赖关系
            dep_contents.append(dep_file.read())
            print("##-100 dep content: {}".format(dep_contents[-1]))
        # 拼接所有依赖内容+自身名称
        file_content = "".join(dep_contents) + this_name
    else:
        file_content = this_name
        print("##-101 content: {}".format(file_content))

    ctx.actions.write(
        output = file_name,
        content = file_content,
    )

    # 收集当前目标+所有依赖的产物,让Bazel输出这些文件
    all_files = [file_name]
    for dep in ctx.attr.deps:
        all_files.extend(dep[DefaultInfo].files.to_list())

    return [
        DefaultInfo(
            files = depset(all_files),
            runfiles = ctx.runfiles(files=all_files)
        ),
    ]

foo_binary = rule(
    implementation = _foo_binary_impl,
    attrs = {
        "deps": attr.label_list(),
    },
)

验证效果

重新执行bazel build //rules/example:foo3后,bazel-bin/rules/example/目录下会同时出现foo1、foo2、foo3三个文件,且foo3的内容为foo1foo2foo3,完全符合预期逻辑。


内容的提问来源于Stack Exchange,提问作者Grrrr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:50:29