Bazel中跨目录导入Proto文件构建失败,请求排查原因
Bazel构建Proto失败原因分析与解决
目录结构
├── proto │ ├── BUILD │ └── hello.proto ├── src │ ├── BUILD │ └── outer.proto └── WORKSPACE
相关文件内容
proto/hello.proto
syntax = "proto3"; package hello; message HelloRequest { string name = 1; } message HelloReply { string msg = 1; }
proto/BUILD
load("@rules_proto//proto:defs.bzl", "proto_library") package(default_visibility = ["//visibility:public"]) proto_library( name = "hello_proto", srcs = ["hello.proto"], )
src/outer.proto
syntax = "proto3"; import "proto/hello.proto"; // 应该使用什么导入路径? message OuterMessage { HelloRequest req = 1; HelloReply resp = 2; }
src/BUILD
load("@rules_proto//proto:defs.bzl", "proto_library") proto_library( name = "outer_proto", srcs = ["outer.proto"], deps = ["//proto:hello_proto"], )
构建错误信息
执行blaze build //src:outer_proto后报错:
src/outer.proto:6:3: "HelloRequest" is not defined. src/outer.proto:7:3: "HelloReply" is not defined. src/outer.proto:3:1: warning: Import proto/hello.proto is unused.
补充Debug命令(翻译后)
使用debug选项得到的protoc执行命令翻译如下:
bazel-out/k8-opt-exec-2B5CBBC6/bin/external/com_google_protobuf/protoc \ --direct_dependencies proto/hello.proto:src/outer.proto \ '--direct_dependencies_violation_msg=%s 已导入,但//src:outer_proto 并未直接依赖包含它的proto_library规则。' \ --descriptor_set_out=bazel-out/k8-fastbuild/bin/src/outer_proto-descriptor-set.proto.bin \ '-Isrc/outer.proto=src/outer.proto' \ '-Iproto/hello.proto=proto/hello.proto' \ src/outer.proto
失败原因
- 未使用包名限定消息类型:
hello.proto中定义了package hello;,所有消息都属于hello包。而outer.proto未指定包名,默认处于全局包,直接写HelloRequest会被认为是当前包下的类型,自然找不到对应定义。 - 导入未被“有效使用”:因为代码里没正确引用导入包中的类型,protoc判定
proto/hello.proto未被实际使用,因此抛出警告。
解决方法
修改src/outer.proto,通过包名限定引用的消息类型即可,有两种实现方式:
方式1:直接使用包名前缀
syntax = "proto3"; import "proto/hello.proto"; message OuterMessage { hello.HelloRequest req = 1; hello.HelloReply resp = 2; }
方式2:使用using声明(Proto3.15及以上版本支持)
如果你的Protobuf版本足够新,可以用using简化引用:
syntax = "proto3"; import "proto/hello.proto"; using hello::HelloRequest; using hello::HelloReply; message OuterMessage { HelloRequest req = 1; HelloReply resp = 2; }
修改后重新执行blaze build //src:outer_proto即可成功构建。
内容的提问来源于stack exchange,提问作者tinkerbeast
相关产品推荐
相关产品推荐

