Bazel规则中填充ProtoInfo报错:‘Provider’对象不可调用,求排查
问题分析与解决
核心错误原因
你直接调用ProtoInfo(...)创建实例,但Bazel的结构化提供者(Structured Provider)不能像普通函数那样直接调用。对于@rules_proto中的ProtoInfo,必须通过proto_common.create_proto_info工具函数来生成合法的实例。
代码修正步骤
- 补充加载
proto_common模块:
load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common")
- 替换实例创建方式,且注意
direct_sources需传入File对象而非字符串路径:
def _impl(ctx): # 假设proto_file是你通过ctx.actions.declare_file生成的File对象 # ... return [proto_common.create_proto_info( ctx = ctx, direct_sources = [proto_file], # 若依赖其他proto库,需补充transitive_sources等字段 )]
- 额外注意点:
direct_sources必须传File类型对象,不能传路径字符串,否则cc_proto_library无法正确识别文件。- 原代码
return语句缺少闭合的]和),属于语法错误,修正时需补上。 - 若规则依赖其他proto目标,要收集它们的
ProtoInfo并传递transitive_sources,保证依赖链完整。
完整修正代码示例
load("@rules_proto//proto:defs.bzl", "ProtoInfo", "proto_common") def _impl(ctx): # 声明要生成的proto文件 proto_file = ctx.actions.declare_file(ctx.attr.name + ".proto") # 添加生成proto文件的动作(示例) ctx.actions.run( inputs = [ctx.file.spec], outputs = [proto_file], arguments = [ctx.file.spec.path, proto_file.path], executable = "//path/to/your:proto_generator", ) # 创建合法的ProtoInfo实例 return [proto_common.create_proto_info( ctx = ctx, direct_sources = [proto_file], )] my_rule = rule( attrs = { "spec": attr.label( mandatory = True, allow_single_file = [".json", ".yaml", ".yml"], ), }, implementation = _impl, provides = [ProtoInfo], )
修正后,你的规则就能正确提供ProtoInfo,可被cc_proto_library作为依赖识别,自动处理生成的proto文件。
内容的提问来源于stack exchange,提问作者montjet
相关产品推荐
相关产品推荐

