31

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

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

syntax = "proto3";

package authenticator;

service Authenticator {...}

生成命令指定我要在同一目录中输出:

protoc --go_out=plugins=grpc:. authenticator.proto

今天我拉出了新版本的协议缓冲区编译器和github.com/golang/protobuf/protoc-gen-go. 第一次运行时收到警告:

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”。

option go_package = "github.com/protocolbuffers/protobuf/examples/go/tutorialpb";

将此选项添加到 proto 文件并重新运行命令后,输出将在此路径中结束,相对于项目根目录。就像是:

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

我尝试了以下替代go_package名称:

  • .
  • authenticator

生成发生在正确的位置,但我收到了警告:

WARNING: Deprecated use of 'go_package' option without a full import path...

那么在不破坏项目布局的情况下,正确的做法是什么呢?

4

10 回答 10

33

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

protoc --go_out=paths=source_relative:./gen -I. authenticator.proto

或者为 grpc 生成以下可以使用

protoc --go_out=plugins=grpc:./gen --go_opt=paths=source_relative authenticator.proto

如果失败,您可能拥有更新版本的 protoc,需要改用以下命令。

protoc --go-grpc_out=./gen --go-grpc_opt=paths=source_relative authenticator.proto

这只是谷歌再次就您应该如何编写和管理代码做出孤立的决定。但是,如果您深入了解有类似问题的人的问题,我发现现在可以使用上述命令。除了添加完整的导入路径,如其他答案所示

option go_package = "github.com/example/path/gen;gen";

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

您可能需要调整 source_relative 的输出位置以供您使用,但至少您最终不会出现路径重复或不得不再次依赖将代码放置在 GOPATH 中。

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

于 2020-06-23T17:36:10.370 回答
9

您只需要添加一个 Go 选项,它将告诉添加相对于 proto 文件的文件。

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

这将使 your_file.pb.go 与 your_file.proto 在同一目录中

于 2020-07-15T17:32:57.840 回答
6

我添加时上述错误消失了

option go_package = "github.com/monkrus/grpc-from0;grpc_from0";如下:

聊天.proto

于 2020-05-23T19:12:54.980 回答
5

如果您使用的是语法 = "proto3"; . 更改 grpc 代码生成处理后必然会出现此问题。修复此问题

第 1 步:通过your_file_with.proto中的这一行

 option go_package = "pb;gen";
   

第 2 步:假设您想在pb 文件夹中生成所有文件,用您的 sutable 名称替换 pb,然后在终端窗口中运行 cmd。在我的情况下,我的所有 protofile 都在项目目录的proto 文件夹中

 protoc -I=proto --go_out=. proto/*.proto
于 2021-01-17T16:43:14.867 回答
3

您好,我将通过阅读文档逐步解释我是如何生成它的

创建文件夹 grpcgo

mkdir grpcgo && cd grpcgo

创建项目

go mod init projectxxx
## Download and install dependencies
go get google.golang.org/protobuf/cmd/protoc-gen-go
go get github.com/golang/protobuf

创建文件 .proto

愿望清单.proto

syntax = "proto3";

package grpcgo; #Folder

option go_package = "pb;gen"; <-- Add 

message Item {
    enum ItemPriority {
        LOW = 0;
        MID = 50;
        HIGH = 100;
    }

    enum ItemStatus {
        INACTIVE = 0;
        ACTIVE = 1;
    }

    string id = 1;
    string wishListId = 2;
    string name = 3; 
    string link = 4;
    double price = 5;

    ItemPriority priority = 6;
    ItemStatus status = 7;

}

message WishList {
    enum WishListStatus {
        INACTIVE = 0;
        ACTIVE = 1;
    }

    string id = 1;
    string name = 2;
    WishListStatus status = 3;

}

编译原型

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

文档:

https://developers.google.com/protocol-buffers/docs/gotutorial

https://blog.friendsofgo.tech/posts/introduccion-a-grpc/

版本:

github.com/golang/protobuf v1.5.2

google.golang.org/protobuf v1.26.0

去版本 go1.16.5 linux/amd64

来自阿根廷的拥抱

于 2021-06-20T00:41:22.150 回答
3

我正在使用 Go,我想在与我所做*.pb.go的相同的文件夹中创建*.proto*.proto

option go_package = "./{Your folder name}";

注意,Your folder name会体现在生成的*.pb.go包中。然后运行:

protoc --go_out=.. *proto
于 2021-08-29T01:24:04.693 回答
2

如果你的包名是 user_service

user_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 {
}

运行以下命令:protoc *.proto --go_out=plugins=grpc:./user_serivce目录中。这应该有效。

于 2021-03-01T03:27:15.423 回答
1

虽然文档没有显示,但我通过将输出目录设置为GOPATH/src.

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

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

于 2020-05-07T20:07:04.080 回答
1

根据 go-grpc-http-rest-microservice-tutorial 项目中的测试 https://medium.com/@amsokol.com/tutorial-how-to-develop-go-grpc-microservice-with-http-rest-endpoint -中间件-kubernetes-af1fff81aeb2

和源代码 https://github.com/amsokol/go-grpc-http-rest-microservice-tutorial/tree/part2

尝试生成 protobufs 但命令一直失败。单独运行命令可能会导致命令静默失败,或者如果我尝试运行以 sudo 为前缀的命令,我可能会收到错误消息:

请使用绝对路径指定一个程序或确保该程序在您的 PATH 系统变量中可用 --go_out: protoc-gen-go: Plugin failed with status code 1。

我知道路径不是问题,我可以回显 $PATH 并看到 GOBIN 和 GOROOT 路径在路径中(尽管我没有直接明确导出这些变量中的任何一个),即在 .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

如果我输入 protoc-gen-go 它不会出错(但似乎将我带到另一个命令行,我 ctrl+c 从中退出),所以这不是问题

长话短说,我注意到确定生成文件的输出路径涉及两个参数,并且如果路径太长,它可能会默默地出错

这是它的工作原理:生成命令,其中前两个只是查找 proto 文件及其依赖项 proto 文件的文件路径,而 go_out 是输出文件的前缀路径:

//cmd to run to generate protobuf and add it to the output directory
protoc --proto_path=api/proto/v1 --proto_path=third_party --go_out=plugins=grpc:./output todo-service.proto

// or below to add it under the pkg directory
protoc --proto_path=api/proto/v1 --proto_path=third_party --go_out=plugins=grpc:./ todo-service.proto

当从所需的选项 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;
// ...

在此处输入图像描述

于 2020-09-14T01:51:50.500 回答
1

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

option go_package = ".;<Your_Import_path>";

例如,我们可以假设包路径为“/pub”,那么语句如下。

option go_package = ".;pub";

然后你可以简单地执行protoc命令来生成pb.go文件

protoc -I=<ABS_PATH_OUTPUT_DIR> --go_out=<ABS_PATH_PROTO_FILE>
于 2021-05-24T18:38:30.550 回答