Skip to content

Latest commit

 

History

History
185 lines (127 loc) · 5.04 KB

File metadata and controls

185 lines (127 loc) · 5.04 KB

Proto 代码生成指南

scripts/gen-protoproto/ 下的 protobuf 协议定义编译为 Go 代码,输出到 api/gen/


生成结果对照

Proto 源文件 生成的 Go 文件
proto/chatview/common/types.proto api/gen/chatview/common/types.pb.go
proto/chatview/auth.proto api/gen/chatview/auth/auth.pb.go + auth_grpc.pb.go
proto/chatview/chat.proto api/gen/chatview/chat/chat.pb.go + chat_grpc.pb.go
proto/chatview/events.proto api/gen/chatview/events/events.pb.go + events_grpc.pb.go
proto/chatview/admin.proto api/gen/chatview/admin/admin.pb.go + admin_grpc.pb.go
  • *.pb.go — 消息类型的序列化/反序列化代码
  • *_grpc.pb.go — gRPC service/client stub 代码

前置条件

1. protoc 编译器

tools/protoc-*/.gitignore 中,不会被 git 跟踪。clone 仓库后需自行准备 protoc。

脚本按以下优先级查找 protoc

优先级 来源 说明
1 $PROTOC 环境变量 显式指定路径,最高优先
2 tools/protoc-*/bin/protoc 本地工具目录,要求恰好一个版本
3 $PATH 中的 protoc 系统已安装的版本

如果 tools/ 下存在多个 protoc 版本,脚本会报错并退出,此时需设置 PROTOC 明确指定。

推荐安装方式: 将 protoc 放入 tools/protoc-<version>-<platform>/bin/,脚本会自动发现。例如:

# 下载并解压到工具目录
wget https://github.com/protocolbuffers/protobuf/releases/download/v34.1/protoc-34.1-linux-x86_64.zip
unzip protoc-34.1-linux-x86_64.zip -d tools/protoc-34.1-linux-x86_64

2. Go protobuf 插件

以下两个二进制文件必须在 $PATH 中:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

安装后确认可用:

which protoc-gen-go
which protoc-gen-go-grpc

通常它们会被安装到 $GOPATH/bin$GOBIN,确保该目录在 $PATH 中。


使用方法

基本用法(推荐)

# 在仓库根目录运行
./scripts/gen-proto

不带参数时直接生成全部代码。

带参数运行

./scripts/gen-proto api
./scripts/gen-proto all
./scripts/gen-proto client
./scripts/gen-proto server

所有参数行为一致——都执行完整生成。参数仅作为未来扩展的预留接口,当前不影响生成范围。

指定 protoc 路径

PROTOC=/usr/local/bin/protoc ./scripts/gen-proto

工作原理

脚本执行以下步骤:

  1. 定位仓库根目录 — 基于脚本自身路径推导,确保从任意目录运行都能正确解析路径
  2. 解析 protoc — 按上述优先级查找可用的 protoc 二进制
  3. 调用 protoc 编译 — 以 proto/-I 根目录运行,参数如下:
protoc
  -I .                           # proto 文件搜索根目录
  --go_out=../api                 # 消息类型输出目录
  --go_opt=module=chatview/api    # 按 Go module 路径裁剪输出
  --go-grpc_out=../api            # gRPC stub 输出目录
  --go-grpc_opt=module=chatview/api
  chatview/common/types.proto     # 5 个源文件
  chatview/auth.proto
  chatview/chat.proto
  chatview/events.proto
  chatview/admin.proto

module=chatview/api 选项确保生成的 Go 文件 package 路径为 chatview/api/gen/chatview/...,与 go.mod 中的 module 路径对齐。


协议层级依赖

Proto 文件之间存在 import 依赖,编译顺序由 protoc 自动处理:

types.proto          ← 无依赖(基础类型定义)
  ↑
auth.proto           ← 无 import(独立服务)
chat.proto           ← import "chatview/common/types.proto"
events.proto         ← import "chatview/common/types.proto"
admin.proto          ← import "chatview/common/types.proto"

因此修改 types.proto 后,所有 5 个文件都需要重新生成。


常见问题

"protoc not found"

protoc 编译器未在 $PROTOCtools/protoc-*/$PATH 中找到。

解决:

  • 在 PATH 中安装 protoc,或
  • 将 protoc 放入 tools/protoc-<version>/bin/,或
  • 设置 PROTOC=/path/to/protoc

"multiple protoc binaries found"

tools/ 下存在多个 protoc-*/ 目录。脚本要求恰好一个。

解决:

  • 删除不用的版本,只保留一个,或
  • 设置 PROTOC 环境变量明确指定

"protoc-gen-go: program not found"

Go protobuf 插件未安装或不在 PATH 中。

解决:

go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
export PATH="$PATH:$(go env GOPATH)/bin"

修改 proto 后客户端/服务端编译报错

生成代码后需要确保 server 和 client 的 go.mod 中的 replace 指令指向本地 api module:

// server/go.mod 和 client/go.mod 中均有:
replace chatview/api => ../api

运行 go mod tidy 更新依赖锁定:

cd api   && go mod tidy
cd server && go mod tidy
cd client && go mod tidy