Protocol buffers protoc go_包的正确格式?

Protocol buffers protoc go_包的正确格式?,protocol-buffers,protoc,grpc-go,Protocol Buffers,Protoc,Grpc Go,我在Go中有一个现有项目,我正在使用协议缓冲区/gRPC。直到最近,go_-package选项还是可选的,并且生成的go-package名称将与proto-package名称相同 此文件位于项目根目录中。生成的代码文件(authenticator.pb.go)位于同一位置。原始文件: syntax = "proto3"; package authenticator; service Authenticator {...} Generation命令指定要在同一目录中输出: protoc --

我在Go中有一个现有项目,我正在使用协议缓冲区/gRPC。直到最近,
go_-package
选项还是可选的,并且生成的go-package名称将与proto-package名称相同

此文件位于项目根目录中。生成的代码文件(
authenticator.pb.go
)位于同一位置。原始文件:

syntax = "proto3";

package authenticator;

service Authenticator {...}
Generation命令指定要在同一目录中输出:

protoc --go_out=plugins=grpc:. authenticator.proto
今天,我推出了新版本的协议缓冲区编译器和
github.com/golang/protobuf/protocgengo
。第一次运行时,a收到警告:

WARNING: Missing 'go_package' option in "authenticator.proto",
please specify it with the full Go package path as
a future release of protoc-gen-go will require this be specified.
See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
建议的链接或多或少是无用的。但本教程更为明确:

go_package选项定义要导入的包的导入路径 将包含此文件的所有生成代码。Go包名称 将是导入路径的最后一个路径组件。例如,我们的 示例将使用包名“tutorialpb”

将此选项添加到proto文件并重新运行该命令后,输出结果将位于相对于项目根的此路径中。比如:

$GOPATH/src/github.com/<org>/authenticator/github.com/<org>/authenticator/authenticator.pb.go

那么,不破坏项目布局的正确方法是什么呢?

尽管文档没有显示,但我通过将输出目录设置为
GOPATH/src
使其工作

protoc --go_out=plugins=grpc:$(go env GOPATH)/src authenticator.proto 

希望这能为其他人节省时间。

当我添加时,上述错误消失了

选项go_package=“github.com/monkrus/grpc-from0;grpc_-from0”如下所示:


对于纯原始世代,您可以执行以下操作

protoc --go_out=paths=source_relative:./gen -I. authenticator.proto
或为grpc生成以下内容:

protoc --go_out=plugins=grpc:./gen --go_opt=paths=source_relative authenticator.proto
这只是谷歌再一次就应该如何编写和管理代码做出孤立的决定。然而,如果你仔细研究了足够多的问题,我发现上面的命令现在可以使用了。除了添加完整的导入路径,如另一个答案所示

option go_package = "github.com/example/path/gen;gen";
按照上面的包和protoc命令,您将在项目根目录中拥有proto文件,模块名为github.com/example/path。然后,您的代码将被放入负责创建的gen文件夹中

您可能需要调整source_relative的输出位置以供使用,但至少不会导致路径重复或不得不再次依赖于将代码放入GOPATH


这可能会因为中的其他更改而中断。不幸的是,二进制名称完全相同,因此如果您遇到问题,请阅读该票据,并尝试切换已安装的版本,直到新的protoc gen go准备好进行生产。

您只需添加go选项,该选项将告诉您相对于proto file添加文件

protoc --go_out=. --go_opt=paths=source_relative your_file.proto 

这将使your_file.pb.go与您的_file.proto位于同一目录中,这是go grpc http rest microservice教程项目中每个测试的结果

和源代码

试图生成protobufs,但命令一直失败。单独运行命令可能会导致命令以静默方式失败,或者如果我尝试运行以sudo为前缀的命令,则可能会出现错误:

请使用绝对路径指定程序,或确保该程序在path系统变量中可用 --go_out:protoc gen go:插件失败,状态代码为1

我知道路径不是问题,我可以回显$path并看到GOBIN和GOROOT路径在path中(尽管我没有直接导出这两个变量),即在.bashrc的底部

# export GOPATH=$HOME/go
# export GOBIN=$HOME/go/bin
# export GOROOT=/usr/local/go/bin
# export PATH=$PATH:$GOBIN:$GOROOT
export PATH=$PATH:$HOME/go/bin:/usr/local/go/bin


$ echo $PATH
/home/tngai/.local/bin:/usr/local/lib/npm/bin:/usr/local/sbin:/usr/local/bin:/usr        /sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/include:/home/tngai/go/bin:/usr/local/go/bin
如果我输入ProtocGenGo,它不会出错(但似乎会将我带到另一个命令行,我用ctrl+c退出),所以这不是问题

长话短说,我注意到,两个参数用于确定生成文件的输出路径,而且如果路径太长,可能会自动出错

这就是它的工作原理: 要生成的命令,其中前两个只是查找原型文件及其依赖关系原型文件的文件路径,以及作为输出文件前缀路径的输出路径:

当从所需选项go_package(输出路径的下一部分)组合到proto文件本身中提到的路径时

//todo-service.proto file
syntax = "proto3";
package v1; //name of the folder this is in
 
import "google/protobuf/timestamp.proto";
import "google/api/annotations.proto"; 
//import "protoc-gen-swagger/options/annotations.proto";

//new required line I had to add, and which also determines output path of gen file(s)
option go_package = "./pkg/api/v1";

//...commented out the swagger generation per testing just the protobuf generation...

// Task we have to do
message ToDo {
// Unique integer identifier of the todo task
int64 id = 1;
// ...

如果您使用的是syntax=“proto3”。在grpc代码生成处理发生更改后,必然会发生此问题。若要解决此问题

步骤1:使用.proto通过您的\u文件\u中的这一行

第2步:假设您要生成pb文件夹中的所有文件用您的可修改名称回复pb,然后在终端窗口中运行cmd。在我的情况下,我的所有协议文件都在项目目录中的proto文件夹中

 protoc -I=proto --go_out=. proto/*.proto

如果您的包名是user\u服务

user\u service.proto
定义如下:

syntax = "proto3";

package user_service;

service UserService {
}

just add option go_package = "./;user_service"; under package user_service; like this :

syntax = "proto3";

package user_service;

option go_package = "./;user_service";

service UserService {
}

user\u serivce
目录中运行以下命令:
protoc*.proto--go\u out=plugins=grpc:./
。这应该是可行的。

您可以简单地定义可选的导入路径,如下所示

option go_package = ".;<Your_Import_path>";
然后,您可以简单地执行protoc命令来生成pb.go文件

protoc-I=--退出=

这看起来就像是一次黑客攻击,你再次被迫将所有的密码放在一个特殊的位置。@mschuett;是的,这确实是一次黑客攻击。更多的变通方法是为了继续工作,直到有人提出更好的解决方案。这可以修复错误,但仍然会为现有项目留下不理想的文件放置位置。问题中已经提到了“go_package”。
--go_opt=Path=source_relative
无疑是解决方法。我排除了另一个答案,因为它包含了更多关于这个问题的背景知识。有没有办法通过protoc更改模块路径?我希望为属于不同模块的客户机和服务器生成Go代码,我尝试使用
Go_opt=module
,但它不适用于 option go_package = "pb;gen";
 protoc -I=proto --go_out=. proto/*.proto
syntax = "proto3";

package user_service;

service UserService {
}

just add option go_package = "./;user_service"; under package user_service; like this :

syntax = "proto3";

package user_service;

option go_package = "./;user_service";

service UserService {
}
option go_package = ".;<Your_Import_path>";
option go_package = ".;pub";
protoc -I=<ABS_PATH_OUTPUT_DIR> --go_out=<ABS_PATH_PROTO_FILE>