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

为何ctx.actions.run无法引用生成文件作为输入?求解决方案

解决Bazel规则中生成文件在沙盒中找不到的问题

问题概述

编写Bazel规则时,通过ctx.actions.expand_template生成脚本,再用ctx.actions.run执行该脚本。已将生成的脚本和依赖规则生成的filelist文件(含文件名称、路径的生成型文件)作为inputs传入,但执行脚本时找不到这些filelist文件。查看沙盒路径发现,filelist存在于execroot/my_rules/bazel-out/k8-fastbuild/bin/my_test子目录中,但脚本引用的沙盒根目录下无对应文件。

问题原因

  1. 变量名错误:代码中ctx.actions.expand_template的output参数使用了未定义的compile_script变量,后续executable引用的路径也对应错误,导致执行的脚本并非预期生成的文件。
  2. 绝对路径无效:ctx.actions.run中使用主机绝对路径compile_script.path指定可执行脚本,沙盒环境无法解析该路径。
  3. 依赖文件收集不完整:若flists_list未正确收集依赖规则生成的所有filelist文件,会导致这些文件未被传入沙盒。

修复方案

1. 修正变量名错误

将ctx.actions.expand_template的output改为之前声明的my_script,确保脚本生成到正确的文件中:

my_script = ctx.actions.declare_file("my_script.sh")
ctx.actions.expand_template(
    output = my_script,  # 修正为已声明的my_script变量
    template = ctx.file._my_template,
    substitutions = {
        "{TOP}": "{}".format(top_name),
        "{FLISTS}": " ".join(["-f {}".format(f.short_path) for f in flists_list]),
        ...
    },
)

2. 使用相对路径指定可执行脚本

在ctx.actions.run中,改用my_script.short_path作为可执行文件路径,确保沙盒环境能正确识别:

ctx.actions.run(
    inputs = depset(compile_srcs),
    outputs = [outputs],
    executable = my_script.short_path,  # 使用沙盒内的相对路径
    env = {
        "HOME": "/home/grrrr",
    },
)

3. 完整收集依赖文件

确认flists_list正确收集了所有依赖规则的输出文件,可通过遍历deps属性获取:

# 从deps中收集所有输出文件到flists_list
flists_list = []
for dep in ctx.attr.deps:
    flists_list.extend(dep.files.to_list())

4. 验证输入文件传递

确保compile_srcs包含所有必要文件(脚本、filelist、源文件),并通过depset传递给ctx.actions.run:

compile_srcs = flists_list + srcs_list + [my_script]
ctx.actions.run(
    inputs = depset(compile_srcs),  # 使用depset确保文件完整传递
    ...
)

修正后的规则片段

def _my_rule_impl(ctx):
    ...
    my_script = ctx.actions.declare_file("my_script.sh")
    ctx.actions.expand_template(
        output = my_script,
        template = ctx.file._my_template,
        substitutions = {
            "{TOP}": "{}".format(top_name),
            "{FLISTS}": " ".join(["-f {}".format(f.short_path) for f in flists_list]),
            ...
        },
    )

    # 收集所有依赖的输出文件
    flists_list = []
    for dep in ctx.attr.deps:
        flists_list.extend(dep.files.to_list())

    compile_srcs = flists_list + srcs_list + [my_script]
    outputs = ctx.outputs.executable

    ctx.actions.run(
        inputs = depset(compile_srcs),
        outputs = [outputs],
        executable = my_script.short_path,
        env = {
            "HOME": "/home/grrrr",
        },
    )

    allfiles = depset(compile_srcs)
    runfiles = ctx.runfiles(files = compile_srcs)

    return [DefaultInfo(
        files = allfiles,
        runfiles = runfiles,
    )]

my_rule = rule(
    implementation = _my_rule_impl,
    attrs = {
        "deps": attr.label_list(
            mandatory = True,
        ),
        "_my_template": attr.label(
            allow_single_file = True,
            default = Label("@my_rules//my_test:my_script.sh.template"),
        ),
        ...
    },
    executable = True,
)

内容的提问来源于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 17:05:19