在Rust中使用prost与tonic时,proto包名'proto.messages.v1'引发编译错误
Rust gRPC编译错误:无法找到
proto模块 目录结构
grpc-protobuf ├── Cargo.toml ├── build.rs ├── proto │ ├── hello │ │ └── hello.proto │ └── messages │ └── hello.proto └── src └── lib.rs
Proto文件内容
消息定义:proto/messages/hello.proto
syntax = "proto3"; package proto.messages.v1; message HelloRequest { string name = 1; } message HelloResponse { string message = 1; }
服务定义:proto/hello/hello.proto
syntax = "proto3"; package hello; import "messages/hello.proto"; service Greeter { rpc SayHello (proto.messages.v1.HelloRequest) returns (proto.messages.v1.HelloResponse) {} }
现有lib.rs代码
pub mod hello { tonic::include_proto!("hello"); } pub mod messages { tonic::include_proto!("proto.messages.v1"); }
编译错误信息
➜ cargo build -p grpc-protobuf Compiling grpc-protobuf v0.1.0 (/Users/gaurav.gahlot/workspace/rusty/rust-grpc/grpc-protobuf) error[E0433]: failed to resolve: could not find `proto` in the crate root --> /Users/gaurav.gahlot/workspace/rusty/rust-grpc/target/debug/build/grpc-protobuf-6fc85551b5cb3a84/out/hello.rs:91:31 | 91 | super::super::proto::messages::v1::HelloRequest, | ^^^^^ could not find `proto` in the crate root error[E0433]: failed to resolve: could not find `proto` in the crate root --> /Users/gaurav.gahlot/workspace/rusty/rust-grpc/target/debug/build/grpc-protobuf-6fc85551b5cb3a84/out/hello.rs:94:43 | 94 | tonic::Response<super::super::proto::messages::v1::HelloResponse>, | ^^^^^ could not find `proto` in the crate root error[E0433]: failed to resolve: could not find `proto` in the crate root --> /Users/gaurav.gahlot/workspace/rusty/rust-grpc/target/debug/build/grpc-protobuf-6fc85551b5cb3a84/out/hello.rs:124:51 |
解决方案
方案1:调整Rust模块结构匹配Proto包层级
Tonic会根据Proto的package字段生成对应的Rust模块路径。你的消息Proto包名为proto.messages.v1,生成的代码期望能通过proto::messages::v1访问,但当前的messages模块直接放在 crate 根目录,导致路径不匹配。
修改src/lib.rs为:
pub mod proto { pub mod messages { pub mod v1 { tonic::include_proto!("proto.messages.v1"); } } } pub mod hello { tonic::include_proto!("hello"); }
方案2:简化Proto包名,减少层级
如果不想用嵌套模块,可以修改Proto的包名:
- 修改
proto/messages/hello.proto的包声明:
syntax = "proto3"; package messages.v1; // 移除前缀`proto.` message HelloRequest { string name = 1; } message HelloResponse { string message = 1; }
- 更新服务Proto中的消息引用:
syntax = "proto3"; package hello; import "messages/hello.proto"; service Greeter { rpc SayHello (messages.v1.HelloRequest) returns (messages.v1.HelloResponse) {} }
- 同步修改
src/lib.rs:
pub mod hello { tonic::include_proto!("hello"); } pub mod messages { pub mod v1 { tonic::include_proto!("messages.v1"); } }
补充:确保build.rs配置正确
如果还未配置build.rs,需要添加以下内容让Tonic正确编译Proto文件:
fn main() -> Result<(), Box<dyn std::error::Error>> { tonic_build::compile_protos("proto/hello/hello.proto")?; tonic_build::compile_protos("proto/messages/hello.proto")?; Ok(()) }
内容的提问来源于stack exchange,提问作者Gaurav Gahlot
相关产品推荐
相关产品推荐

