Go SDK的proto代码生成
Dapr的Go SDK中从protos生成代码
准备工作
准备protoc
安装Protoc,目前 daprd 要求的版本是 v3.14.0。
具体见 Daprd Proto代码生成
sdk 和 daprd保持一致,但实际目前go sdk采用的是 protoc 3.11.2。
将proto生成源码
现在 go sdk的make file 提供了 protos 命令来从proto生成go代码:
$ make protos
# 下载安装gogoreplace
go install github.com/gogo/protobuf/gogoreplace
go: finding module for package github.com/gogo/protobuf/gogoreplace
go: found github.com/gogo/protobuf/gogoreplace in github.com/gogo/protobuf v1.3.2
# 删除本地的proto文件
rm -f ./dapr/proto/common/v1/*
rm -f ./dapr/proto/runtime/v1/*
# 从 dapr/dapr 仓库下载 common.proto 文件到本地
wget -q https://raw.githubusercontent.com/dapr/dapr/master/dapr/proto//common/v1/common.proto -O ./dapr/proto/common/v1/common.proto
# 使用 gogoreplace 工具替换 common.proto 文件中的 go_package
gogoreplace 'option go_package = "github.com/dapr/dapr/pkg/proto/common/v1;common";' \
'option go_package = "github.com/dapr/go-sdk/dapr/proto/common/v1;common";' \
./dapr/proto/common/v1/common.proto
wget -q https://raw.githubusercontent.com/dapr/dapr/master/dapr/proto//runtime/v1/appcallback.proto -O ./dapr/proto/runtime/v1/appcallback.proto
gogoreplace 'option go_package = "github.com/dapr/dapr/pkg/proto/runtime/v1;runtime";' \
'option go_package = "github.com/dapr/go-sdk/dapr/proto/runtime/v1;runtime";' \
./dapr/proto/runtime/v1/appcallback.proto
wget -q https://raw.githubusercontent.com/dapr/dapr/master/dapr/proto//runtime/v1/dapr.proto -O ./dapr/proto/runtime/v1/dapr.proto
gogoreplace 'option go_package = "github.com/dapr/dapr/pkg/proto/runtime/v1;runtime";' \
'option go_package = "github.com/dapr/go-sdk/dapr/proto/runtime/v1;runtime";' \
./dapr/proto/runtime/v1/dapr.proto
# 从proto文件生成go代码
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
dapr/proto/common/v1/common.proto
protoc --go_out=. --go_opt=paths=source_relative \
--go-grpc_out=. --go-grpc_opt=paths=source_relative \
dapr/proto/runtime/v1/*.proto
# 删除刚才下载到本地的proto
rm -f ./dapr/proto/common/v1/*.proto
rm -f ./dapr/proto/runtime/v1/*.proto
遇到的问题
gogoreplace的安装
不知为何我遇到下面的报错:
$ make protos
go install github.com/gogo/protobuf/gogoreplace
cannot find package "." in:
/home/sky/work/code/skyao/go-sdk/vendor/github.com/gogo/protobuf/gogoreplace
make: *** [Makefile:48:protos] 错误 1
单独执行这个 go install 命令也是同样错误:
$ go install github.com/gogo/protobuf/gogoreplace
cannot find package "." in:
/home/sky/work/code/skyao/go-sdk/vendor/github.com/gogo/protobuf/gogoreplace
解决的方法是进入上一级目录(不要在go-sdk目录下)进行安装:
$ cd ..
$ go install github.com/gogo/protobuf/gogoreplace
go install: version is required when current directory is not in a module
Try 'go install github.com/gogo/protobuf/gogoreplace@latest' to install the latest version
$ go install github.com/gogo/protobuf/gogoreplace@latest
然后临时注释掉这一行:
#go install github.com/gogo/protobuf/gogoreplace
方法有点恶心,主要是没有找到问题所在。
cgo报错stdlib.h找不到
在ubuntu 20.04新系统上遇到这个错误:
$ make test
go mod tidy
go test -count=1 \
-race \
-coverprofile=coverage.txt \
-covermode=atomic \
./...
# runtime/cgo
_cgo_export.c:3:10: fatal error: stdlib.h: 没有那个文件或目录
3 | #include <stdlib.h>
| ^~~~~~~~~~
compilation terminated.
这是因为 ubuntu 默认没有C和C++编译环境,执行以下命令安装即可:
$ sudo aptitude install build-essential
后记:更新protoc版本
发现 go sdk 使用的protoc 版本是 v3.11.2,而之前我为了满足 dapr/dapr 仓库的要求安装的是 protoc v3.14.0。两个版本生成的代码会有一些细微的差异,也就造成了生成的代码会合git 仓库中的现有代码不同。
在不同仓库之间切换使用不同的 protoc 版本实在是太不方便了,最简单的方法还是统一到同一个版本。
提交了issue和PR 给到社区,希望可以升级 go sdk 的 protoc 版本到 v3.14.0: