2023-03-29

2023-04-03  本文已影响0人  癞痢头

protobuf go

protoc 编译 proto文件生成go的一些说明和实验:

protoc 生成 go 的语法:

    protoc -I=$BASE_SRC_DIR --go_out=$DST_DIR --go_opt=${options} $SUB_SRC_DIR/addressbook.proto

我们有如下的项目,目录结构 和 bar.proto 文件,下文所涉及的生成测试都基于这个目录结构和文件:

.
├── build.sh
├── out      
├── protos
│   └── bar.proto
└── readme.md


syntax="proto3";

option go_package="example.com/project/foo";

message test {
  string id =1;
}

一、-I 参数

指定定义文件proto的路径。通俗来讲就是告诉protoc从哪些文件夹下,寻找proto文件,默认从当前文件夹下找。

实验


     # case1. BASE_SRC_DIR=./
          protoc -I=./ --go_out=out --go_opt=paths=import bar.proto

          # Could not make proto path relative: bar.proto: No such file or directory

     #  case2. BASE_SRC_DIR=./
          protoc -I=./ --go_out=out --go_opt=paths=import protos/bar.proto

     #  case3. BASE_SRC_DIR=protos
          protoc -I=./protos --go_out=out --go_opt=paths=import bar.proto

     #  case4. BASE_SRC_DIR=protos
          protoc -I=./protos --go_out=out --go_opt=paths=import protos/bar.proto
          

其中,case1 返回找不到bar.proto 文件,case2、case3和case4 皆顺利生成。

case2,case3能执行成功是,在protoc的执行路径下,存在文件 BASE_SRC_DIR +SUB_SRC_DIR + {filename}.proto, 即 `lsBASE_SRC_DIR + SUB_SRC_DIR +{filename}.proto` 是存在的。

case4 中: protos/protos/bar.proto (BASE_SRC_DIR +SUB_SRC_DIR + {filename}.proto 拼接后的值) 不存在,会在当前文件夹下找 protos/bar.proto (SUB_SRC_DIR + ${filename}.proto 的值)

注意:case4 和 case3,及case2的结果相同,但过程是不同的。

二、 --go_out

go_out 的参数是个文件路径,指定生成文件的输出目录,此目录需事先存在。

go_opt 和 go import 决定的路径,在此跟路径之下。

三、 --go_opt 选项参数

还是以上面的文件为例: protos/bar.proto 文件,根据编译中 --go_opt的不同,生成文件的位置也不同

默认参数:指定生成文件输出路径。 默认行为是指定生成文[.pb.go]件位于 proto 定义的导出路径的后面;

protoc -I=./ --go_out=out --go_opt=paths=import protos/bar.proto
.
├── art.md
├── build.sh
├── out
│   └── example.com
│       └── project
│           └── foo
│               └── bar.pb.go
├── protos
│   └── bar.proto
└── readme.md

文件位置位于 导入路径 减去$PREFIX 的部分

protoc -I=./ --go_out=out --go_opt=module=example.com/project protos/bar.proto
.
├── art.md
├── build.sh
├── out
│   └── foo
│       └── bar.pb.go
├── protos
│   └── bar.proto
└── readme.md 

该方式可生成和定义文件一致的目录

protoc -I=./ --go_out=out --go_opt=paths=source_relative protos/bar.proto
.
├── art.md
├── build.sh
├── out
│   └── protos
│       └── bar.pb.go
├── protos
│   └── bar.proto
└── readme.md

四、. package 指定方式

为了生成 Go 代码,必须为每个 .proto 文件提供 Go 包的导入路径(包括那些被生成的 .proto 文件传递依赖的文件)。

指定 Go 导入路径的方式有两种:


syntax="proto3";

option go_package="example.com/project/foo;package_name";

.
├── art.md
├── build.sh
├── out
│   └── example.com
│       └── project
│           └── foo
│               └── bar.pb.go
├── protos
│   └── bar.proto
└── readme.md

在 protoc 调用生成的时候,使用 M${PROTO_FILE}=${GO_IMPORT_PATH} 方式,更改指定包导入路径

仍然使用上面的文件为例:

protoc --proto_path=src \
  --go_opt=Mprotos/buzz.proto=example.com/project/protos/fizz \
  --go_opt=Mprotos/bar.proto=example.com/project/protos/foo \
  protos/buzz.proto protos/bar.proto

如果两种同时指定,命令行中指定的优先级别高。

参考文件

上一篇下一篇

猜你喜欢

热点阅读