我很难弄清楚protoc
命令和go插件。
以下两者有何不同:
protoc \
# Directory where you want the compiler to write your Go output.
--go_out=.
# vs ?
--go_opt=paths=source_relative
# vs ?
--go-grpc_out=.
# vs ?
--go-grpc_opt=paths=source_relative
字符串
如果--go_opt
生成
<name>.pb.go
文件
和--go-grpc_opt
生成
<name>_grpc.pb.go
文件
为什么要有--go_out
?
你能解释一下协议吗?文档没有提到--go-grpc_opt
?
和protoc -h
甚至不列出去作为一个OUT_DIR?
注意:我使用此doc安装
2条答案
按热度按时间kninwzqo1#
为什么要出去?
所以,这里要理解的是,gRPC与Protocol Buffers不同,gRPC使用Protocol Buffers,但也有其他框架也在使用它们。所以我们需要两者都产生。
现在,为了生成与Protocol buffer相关的代码,您需要使用您提到的
--go_out
。但是对于gRPC代码,您需要使用--go-grpc_out
。和--go-grpc_opt生成grpc.pb.go文件
不,
--go-grpc_out
有。你能在协议上加一些光吗?文档不会留下任何关于-go-grpc_opt的东西?
然后,在生成代码之前,您可以传递一些选项,这就是
--go_opt
和--go-grpc_opt
的用途。第一个传递Protobuf生成选项,第二个传递gRPC生成选项。选项非常模糊,并且没有所有选项的官方列表,但是您使用source_relative
(告诉protoc使用相对路径)作为路径,还有module
选项(帮助protoc知道要在适当的文件夹中生成的go模块名称)而protoc -h甚至没有将go列为OUT_DIR?
最后,protoc并不正式支持Go作为输出,你需要安装一个外部插件,这就是为什么
protoc -h
不显示--go_out
。相关讨论可以在here中找到。tkclm6bt2#
protoc
编译器支持不同的标志或选项,您在命令行上使用的标志决定了生成的go代码将被放置在哪里。这些标志的官方[文档][1](至少对于
paths=source_relative
和module=$PREFIX
)不是很清楚,很难理解。paths=source_relative
官方文件是这样说的
如果指定了paths=source_relative标志,则输出文件将与输入文件放在同一相对目录中。例如,输入文件protos/buzz.proto会导致输出文件protos/buzz. pb. go。
上面的语句可能会令人困惑,因为它没有提供完整的上下文和文件夹布局,说明文件如何放置在磁盘上。
对我来说,这个标志意味着当使用时,在
--go_out
指定的目录中生成go代码,并确保生成的go代码文件的目录树结构与proto文件的目录树结构相匹配。假设我们有以下目录结构
字符串
考虑以下示例
型
在上面的例子中,我们设置了
--proto_path=src/protos
,这意味着实际proto文件的目录路径将是foo.proto
和bar/baz.proto
,而pb文件将在当前目录(--go_out=.
)中创建为foo.pb.go
和bar/baz.pb.go
。现在让我们将上面命令中的
--proto_path
更改为src
,看看会发生什么。型
这一次创建了一个新的
protos
目录,在这个目录下我们有生成的go文件,为什么?因为当我们更改--proto-path=src
时,proto文件的目录结构更改为protos/foo.proto
和protos/bar/baz.proto
。现在让我们最后把
--go_out
也放在这里,看看会发生什么型
这与上一个示例完全相似,只是我们提供了一个自定义目录来保存生成的代码。
模块=$PREFIX
如果指定了module=$PREFIX标志,则输出文件将被放置在以Go包的导入路径命名的目录中,但指定的目录前缀将从输出文件名中删除。例如,输入文件protos/buzz.proto的Go导入路径为example.com/project/protos/fizz指定为模块前缀,输出文件为protos/fizz/buzz. pb. go。在模块路径之外生成任何Go包都会导致错误。此模式对于将生成的文件直接输出到Go模块中非常有用。
让我们看看这一点,以及在行动中,考虑以下proto文件
型
请注意,我故意从
go_package
中删除了src
,以显示此标志的行为型
我们看到
greet
目录,其中包含pb文件。因此,它基本上从go_package
中删除了前缀(github.com/rbhanot/dummy-app
),然后在当前目录(--go_out=.
)中实际创建了go包。现在让我们更改
go_package = "github.com/rbhanot/dummy-app/src/greet";
,运行上面的命令会产生以下结果型
这一次,我们看到在
src
目录中生成的greet包。最后,让我们在这里也抛出相同的
--go_out=out
型
这一次生成的代码没有放在
src
中,而是放在out
中,请注意目录结构以及src/greet/foo.pb.go
。我希望这能让事情变得更清楚(至少对我来说是这样),关于这些标志的行为。[1]:https://protobuf.dev/reference/go/go-generated/#invocation