protoc命令编译
protoc [opt...] file.proto
/* 举例 */
protoc --go_out=../pkg/proto go_opt=paths=source_relative *.proto
--go_out=../pkg/proto
原型是--xxxx_out=....
,其中xxxx
表示所使用的插件名为protoc-gen-xxxx.exe
。等号后面表示插件执行后生成到的目标路径。--xxxx_opt=paths=source_relative
,表示生成的.pb.go文件路径不依赖于.proto文件中的option go_package
配置项,直接在go_out指定的目录下生成.pb.go文件(.pb.go文件的package名还是由option go_package决定)。
protoc命令的插件解析步骤如下
1、解析proto文件,类似于AST树的解析,将整个proto文件有用的语法内容提取出来。
2、将解析的结果转为成二进制流,然后传入到protoc-gen-xxxx
标准输入。也就是说protoc会去程序执行路径去找protoc-gen-go 这个二进制,将解析结果写入到这个程序的标准输入。如果命令是–go_out,那么找到是protoc-gen-go,如果自己定义一个插件叫xxxx,那么--xxxx_out
找到就是protoc-gen-xxxx
了。所以我们得确保有这个二进制执行文件,要不然会报找不到的错误。
3、protoc-gen-xxxx
必须实现从标准输入读取上面解析完的二进制流,然后将得到的proto 信息按照自己的语言生成代码,最后将输出的代码写回到标准输出
4、protoc接收protoc-gen-xxxx
的标准输出,然后写入文件。
实际调用过程中,可以将插件二进制文件放在环境变量PATH中,也可直接通过--plugin=[ plugin-name=plugin-path, ....]
传给protoc。
插件解析补充案例:
在框架bin目录下存在protoc插件二进制文件文件:
现在希望把它和框架剥离开,复制插件文件到自己工程的路径下:
- 由于在环境变量中的配置,插件默认会指向原本框架的bin目录中。
- 尽管protoc.exe被指定,但是其他插件默认也不会执行与被执行protoc.exe同层目录的文件,还是会从原框架中查找。
- 使用命令参数指定插件路径:
--plugin=插件名字=包含exe名字的完整路径
。
实际命令如下:
自己工程插件exe存放位置/protoc.exe --xxx-proxy_out=./pkg/proto --xxx-proxy_opt=paths=source_relative --plugin=protoc-gen-xxx-proxy=./自己工程插件exe存放位置/protoc-gen-xxx-proxy.exe -I=proto .\proto\*.proto