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

Bazel自定义run_shell规则如何配置data依赖使其进入执行沙箱

Bazel自定义规则data依赖不生效解决方案

问题描述

查看Bazel shell_command规则示例时,尝试给自定义规则添加data依赖。按照官方文档配置label_list类型的data属性后,data依赖不会被自动拷贝到沙箱中。
当前规则实现代码:

# This example copied from docs

def _emit_size_impl(ctx):
    in_file = ctx.file.file
    out_file = ctx.actions.declare_file("%s.pylint" % ctx.attr.name)
    ctx.actions.run_shell(
        inputs = [in_file],
        outputs = [out_file],
        command = "wc -c '%s' > '%s'" % (in_file.path, out_file.path),
    )   
    return [DefaultInfo(files = depset([out_file]),)]  

emit_size = rule(
    implementation = _emit_size_impl,
    attrs = { 
        "file": attr.label(mandatory = True,allow_single_file = True,),
        "data": attr.label_list(allow_files = True),
      # ^^^^^^^ 仅声明该属性不足以将data依赖拷贝到沙箱
    },
)

规则调用方式:

emit_size(name = "my_name", file = "my_file", data = ["my_data"])

预期效果:命令执行前my_data会被拷贝到bazel-out对应的沙箱目录中。

根因

仅在attrs中声明data属性不会自动将对应文件加入action的输入列表。Bazel不会隐式推断action需要的依赖文件,所有沙箱中需要访问的文件必须显式传入action的inputs参数,否则不会被提前准备到沙箱环境,这是Bazel保证增量构建正确性的核心设计。

修复方案

  • 通过ctx.files.data获取data属性关联的所有文件列表
  • 将data文件和原有的输入文件合并,传入run_shell的inputs参数
  • (可选)如果需要让依赖当前规则的上层目标也能拿到这些data依赖,将data文件加入DefaultInfo的runfiles中传递

修改后的完整实现:

def _emit_size_impl(ctx):
    in_file = ctx.file.file
    out_file = ctx.actions.declare_file("%s.pylint" % ctx.attr.name)
    # 获取data属性关联的所有文件
    data_files = ctx.files.data

    ctx.actions.run_shell(
        # 合并所有输入文件,Bazel会自动将列表内所有文件准备到沙箱
        inputs = [in_file] + data_files,
        outputs = [out_file],
        # 命令中如果需要访问data文件,直接通过<变量>.path获取路径即可
        command = "wc -c '%s' > '%s'" % (in_file.path, out_file.path),
    )

    return [
        DefaultInfo(
            files = depset([out_file]),
            # 可选:向上层规则传递data运行依赖
            runfiles = ctx.runfiles(files = data_files)
        )
    ]

emit_size = rule(
    implementation = _emit_size_impl,
    attrs = { 
        "file": attr.label(
            mandatory = True,
            allow_single_file = True,
        ),
        "data": attr.label_list(allow_files = True),
    },
)

进阶注意事项

如果data依赖包含其他规则产出的可执行文件、或自身带有运行时依赖,直接用ctx.files.data会漏掉传递性依赖,需要从依赖的DefaultInfo中收集完整的文件和runfiles:

data_inputs = []
for dep in ctx.attr.data:
    # 收集依赖本身的产出文件
    data_inputs.extend(dep[DefaultInfo].files.to_list())
    # 收集依赖的传递性运行文件
    data_inputs.extend(dep[DefaultInfo].default_runfiles.files.to_list())

收集完成后再将data_inputs合并入action的inputs参数即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:54:30