Bazel自定义zip规则无法生成输出文件问题解决
问题:Bazel自定义zip规则输出文件未创建但日志显示文件已添加
在Mac上编写Bazel自定义zip规则时,执行bazel build archive显示已成功添加文件,但报错输出文件all.zip未创建,而用genrule实现的版本可正常运行。
问题根源
自定义规则存在三个关键错误:
- 输出路径错误:直接使用
ctx.attr.out作为zip的输出路径,而Bazel在沙箱环境中要求输出文件必须对应ctx.actions.declare_file返回的路径 - 参数传递格式错误:
arguments=[args]会把整个args对象作为单个参数传递给zip,导致参数格式混乱 - 缺少zip的
-j参数:默认zip会保留文件的目录结构,而Bazel沙箱中的文件路径和预期不符,需要用-j忽略目录直接打包文件
修改后的自定义规则
def _archive(ctx): out_file = ctx.actions.declare_file(ctx.attr.out) args = ctx.actions.args() # 添加zip的-j参数,忽略目录结构 args.add("-j") # 指定输出文件为沙箱中的正确路径 args.add(out_file.path) # 添加所有输入文件的路径 args.add_all(ctx.files.files) ctx.actions.run( executable = "zip", # 直接传递args,而非包裹在列表中 arguments = args, inputs = ctx.files.files, outputs = [out_file], use_default_shell_env = True, ) return [DefaultInfo(files=depset([out_file]))] archive = rule( implementation = _archive, attrs = { "files": attr.label_list(allow_files=True), "out": attr.string(mandatory=True), }, )
关键修改点说明
- 添加
-j参数:让zip直接将文件添加到压缩包根目录,避免因沙箱内文件路径导致的打包问题 - 使用
out_file.path作为输出路径:确保zip在Bazel沙箱的正确位置生成输出文件,和Bazel声明的输出文件路径匹配 - 修正
arguments传递方式:直接传递args而非[args],保证每个参数被正确解析为独立的命令行参数
验证
重新执行bazel build archive,此时zip会在正确的位置生成all.zip,Bazel能正常识别到输出文件,构建成功。
内容的提问来源于stack exchange,提问作者guy mograbi
相关产品推荐
相关产品推荐

