如何在Bazel中编写返回sha256sum的函数或宏?
在Bazel中直接获取文件SHA256值的方法
你当前的规则会生成包含SHA256值的文件,若要直接返回哈希值而非生成文件,可通过以下两种方案实现:
方案1:使用Bazel内置哈希计算+自定义Provider(推荐)
Bazel提供了内置的ctx.actions.sha256方法计算文件哈希,无需调用外部sha256sum命令,跨平台且更高效。我们可以通过自定义Provider在规则间传递哈希值:
# 定义自定义Provider,用于传递SHA256值 Sha256Info = provider( fields = { "value": "文件的SHA256哈希纯值", }, ) def _impl(ctx): # 直接调用Bazel内置方法计算SHA256 sha256_raw = ctx.actions.sha256(ctx.file.src) # 保留原生成文件的逻辑(可选,若不需要可删除) ctx.actions.run_shell( outputs = [ctx.outputs.sha256], inputs = [ctx.file.src], use_default_shell_env = True, # 提取纯哈希值写入文件,避免带文件名 command = "sha256sum {} | awk '{{print $1}}' > {}".format(ctx.file.src.path, ctx.outputs.sha256.path), ) # 同时返回文件输出和哈希值Provider return [ DefaultInfo(files = depset([ctx.outputs.sha256])), Sha256Info(value = sha256_raw), ] _hashes = rule( implementation = _impl, attrs = { "src": attr.label(mandatory = True, allow_single_file = True), "sha256": attr.output(), }, )
在其他规则中可直接通过Provider获取哈希值:
def _consumer_rule_impl(ctx): # 从依赖目标中提取SHA256值 target_sha256 = ctx.attr.target[Sha256Info].value # 示例:用哈希值执行后续操作 ctx.actions.run_shell( command = "echo '目标文件SHA256: {}'".format(target_sha256), ) consumer_rule = rule( implementation = _consumer_rule_impl, attrs = { "target": attr.label(mandatory = True, providers = [Sha256Info]), }, )
方案2:宏封装简化BUILD文件使用
若想在BUILD文件中快速生成哈希相关目标,可封装宏来简化调用:
def get_file_sha256(name, src, **kwargs): # 生成哈希计算目标 _hashes( name = "{}_hash_calc".format(name), src = src, sha256 = "{}_sha256.txt".format(name), **kwargs ) # 生成可直接获取哈希值的目标(通过Provider读取) native.genrule( name = name, srcs = [":{}_hash_calc".format(name)], outs = ["{}_sha256_result.txt".format(name)], cmd = "echo $(locations :{}_hash_calc)[Sha256Info].value > $@".format(name), )
在BUILD文件中调用宏:
get_file_sha256( name = "my_config_sha256", src = "config.yaml", )
关键注意点
ctx.actions.sha256是Bazel原生API,比外部命令更可靠,无需依赖系统环境中的sha256sum工具。- 若必须使用外部命令,需通过
awk或cut提取纯哈希值,避免输出中混入文件名。 - 自定义Provider是Bazel中传递非文件类型数据的标准方式,适合在规则间共享哈希这类计算结果。
内容的提问来源于stack exchange,提问作者Maneesh Singh
相关产品推荐
相关产品推荐

