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

如何将bazel run第一个规则的执行结果文件传递给第二个Bazel规则?

问题本质与解决方案

Bazel的构建阶段和运行阶段是完全隔离的:你通过bazel run第一个规则时生成的myfile.txt属于运行时产物,不在Bazel的构建追踪体系内,因此第二个规则在构建阶段根本无法获取到它。

正确的做法是把生成myfile.txt的逻辑移到第一个规则的构建动作中,让这个文件成为第一个规则的输出产物,这样就能被第二个规则正常依赖。

修改后的规则代码示例

1. 第一个规则:在构建阶段生成myfile.txt

def _1st_rule_impl(ctx):
    # 生成可执行脚本(保留原逻辑,可选)
    out_script = ctx.outputs.executable
    template = ctx.file.my_template
    ctx.actions.expand_template(
        output = out_script,
        template = template,
        substitutions = {
            "{ARG1}": ctx.attr.my_file_name,
            "{ARG2}": ctx.attr.my_file_content,
        }
    )

    # 核心修改:在构建阶段生成myfile.txt,作为规则输出
    my_file = ctx.actions.declare_file(ctx.attr.my_file_name)
    ctx.actions.run_shell(
        outputs = [my_file],
        command = "echo '{content}' > {output}".format(
            content = ctx.attr.my_file_content,
            output = my_file.path,
        ),
    )

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

1st_rule = rule(
    implementation = _1st_rule_impl,
    attrs = {
        "my_template": attr.label(
            allow_single_file = True,
            default = Label("@my_test//my_rules:my_script.sh.template"),
        ),
        "my_file_name": attr.string(
            default = "myfile.txt",
        ),
        "my_file_content": attr.string(
            default = "hello world",
        ),
    },
    executable = True,
    outputs = {
        # 声明输出文件,让Bazel追踪它
        "my_file": "%{my_file_name}",
    },
)

2. 第二个规则:获取第一个规则的输出文件

def _2nd_rule_impl(ctx):
    input_files = []
    # 遍历依赖,提取第一个规则生成的所有输出文件
    for dep in ctx.attr.deps:
        input_files.extend(dep[DefaultInfo].files.to_list())
        # 如果需要精准筛选myfile.txt,可添加过滤逻辑
        # for f in dep[DefaultInfo].files.to_list():
        #     if f.basename == "myfile.txt":
        #         input_files.append(f)

    # 示例:生成使用该文件的可执行脚本
    out = ctx.outputs.executable
    ctx.actions.write(
        output = out,
        content = "#!/bin/sh\necho 读取文件内容:\ncat {}".format(
            input_files[0].path if input_files else "",
        ),
        is_executable = True,
    )

    return [
        DefaultInfo(
            files = depset([out]),
            runfiles = ctx.runfiles(files = input_files + [out])
        )
    ]

2nd_rule = rule(
    implementation = _2nd_rule_impl,
    attrs = {
        "deps": attr.label_list(
            mandatory = True,
        ),
    },
    executable = True,
)

3. BUILD文件(无需大幅修改)

1st_rule(
    name = "my_1st_rule",
    my_file_name = "myfile.txt",
    my_file_content = "hello world",
)

2nd_rule(
    name = "my_2nd_rule",
    deps = [
        ":my_1st_rule",
    ],
)

验证方式

执行bazel run :my_2nd_rule,就能看到第二个规则成功读取到第一个规则在构建阶段生成的myfile.txt内容。

内容的提问来源于stack exchange,提问作者Grrrr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:40:42