Bazel中如何将rules_pkg创建的tar目标转换为zip目标
Bazel 下将 rules_pkg 生成的 tar 包转为 zip 包的方案
直接把pkg_tar目标作为pkg_zip的srcs输入是不可行的:这种写法最终生成的zip包内只会包含tar文件本身,不会是tar解压后的目录结构,完全达不到预期。
你之前实现的genrule方案无法满足Bazel确定性构建要求,核心问题有三个:
- 依赖系统自带的
tar/zip命令,不同环境下命令版本、默认参数存在差异,输出本身不可控 - 系统压缩命令不会主动固定文件修改时间、权限位、压缩包内的文件排列顺序,每次构建输出的文件哈希都会变化
- 解压操作未做独立路径隔离,沙箱配置异常时存在污染工作区的风险
最优方案:同一份源直接输出两种格式包
99%的场景下完全不需要做tar到zip的格式转换:pkg_tar和pkg_zip是平级的打包规则,支持完全一致的输入源。你可以先通过pkg_files统一收拢所有要打包的文件集合,再分别传入两个打包规则生成对应格式的产物,全流程由rules_pkg原生逻辑保证构建确定性,输出的tar和zip内容完全一致,稳定性远高于自定义转换逻辑。
以你给出的AWS Lambda打包场景为例,适配你当前使用的rules_pkg 0.7.0版本的写法如下,无需升级依赖:
# 统一收拢待打包文件,避免tar和zip两套配置出现不一致 pkg_files( name = "bundle_contents", srcs = [":aws-lambda"], include_runfiles = True, ) pkg_tar( name = "bundle-tar", srcs = [":bundle_contents"], package_dir = "/", ) pkg_zip( name = "bundle-zip", srcs = [":bundle_contents"], package_dir = "", # 对应tar包的根目录打包逻辑 )
特殊场景的转换思路
如果你遇到必须从现成tar包(比如第三方提供的预构建外部依赖tar)生成zip的场景,你提到的@bazel_tools//tools/zip:zipper工具确实可以实现确定性转换,但不要通过genrule调用系统命令实现,正确的实现要点为:
- 用rules_pkg内置的tar解析逻辑读取tar内的文件列表、权限、内容,不依赖系统tar命令
- 调用zipper时写死所有压缩参数,将所有文件的修改时间统一设为固定值,按固定顺序排列文件后再压缩,保证每次构建输出的哈希完全一致
这类场景属于小众需求,绝大多数自研构建场景直接使用上述双输出方案即可,不需要额外编写自定义转换规则。
你当前使用的rules_pkg依赖配置可正常支持上述写法,参考配置如下:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "rules_pkg", urls = [ "https://mirror.bazel.build/github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz", "https://github.com/bazelbuild/rules_pkg/releases/download/0.7.0/rules_pkg-0.7.0.tar.gz", ], sha256 = "8a298e832762eda1830597d64fe7db58178aa84cd5926d76d5b744d6558941c2", ) load("@rules_pkg//:deps.bzl", "rules_pkg_dependencies") rules_pkg_dependencies()
内容的提问来源于stack exchange,提问作者sdgfsdh
相关产品推荐
相关产品推荐

