考虑以下带有 Go 模块的示例项目 github.com/kurtpeek/proto-example
和以下目录结构(.proto
目录中的 proto
文件和 gen/go
中生成的 Go 代码):
.
├── gen
│ └── go
│ ├── author
│ │ └── author.pb.go
│ └── book
│ └── book.pb.go
├── go.mod
├── go.sum
├── main.go
└── proto
├── author
│ └── author.proto
└── book
└── book.proto
这里
author.proto
读syntax="proto3";
package author;
message Author {
string name = 1;
}
和
book.proto
进口 author.proto
像这样:syntax="proto3";
package book;
import "author/author.proto";
message Book {
string title = 1;
author.Author author = 2;
}
我已经生成了
.pb.go
文件,在 proto/
目录,运行protoc book/book.proto --go_out=../gen/go
和
protoc author/author.proto --go_out=../gen/go
问题是
author
下的包名被导入 book.pb.go
简直是"author"
:// Code generated by protoc-gen-go. DO NOT EDIT.
// source: book/book.proto
package book
import (
author "author"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
)
// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
type Book struct {
Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
Author *author.Author `protobuf:"bytes,2,opt,name=author,proto3" json:"author,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Book) Reset() { *m = Book{} }
func (m *Book) String() string { return proto.CompactTextString(m) }
func (*Book) ProtoMessage() {}
func (*Book) Descriptor() ([]byte, []int) {
return fileDescriptor_ee9082fb44230b1b, []int{0}
}
func (m *Book) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Book.Unmarshal(m, b)
}
func (m *Book) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Book.Marshal(b, m, deterministic)
}
func (m *Book) XXX_Merge(src proto.Message) {
xxx_messageInfo_Book.Merge(m, src)
}
func (m *Book) XXX_Size() int {
return xxx_messageInfo_Book.Size(m)
}
func (m *Book) XXX_DiscardUnknown() {
xxx_messageInfo_Book.DiscardUnknown(m)
}
var xxx_messageInfo_Book proto.InternalMessageInfo
func (m *Book) GetTitle() string {
if m != nil {
return m.Title
}
return ""
}
func (m *Book) GetAuthor() *author.Author {
if m != nil {
return m.Author
}
return nil
}
func init() {
proto.RegisterType((*Book)(nil), "book.Book")
}
func init() { proto.RegisterFile("book/book.proto", fileDescriptor_ee9082fb44230b1b) }
var fileDescriptor_ee9082fb44230b1b = []byte{
// 108 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x4f, 0xca, 0xcf, 0xcf,
0xd6, 0x07, 0x11, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x2c, 0x20, 0xb6, 0x94, 0x70, 0x62,
0x69, 0x49, 0x46, 0x7e, 0x91, 0x3e, 0x84, 0x82, 0x48, 0x29, 0xb9, 0x70, 0xb1, 0x38, 0xe5, 0xe7,
0x67, 0x0b, 0x89, 0x70, 0xb1, 0x96, 0x64, 0x96, 0xe4, 0xa4, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70,
0x06, 0x41, 0x38, 0x42, 0x6a, 0x5c, 0x6c, 0x10, 0xd5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xdc, 0x46,
0x7c, 0x7a, 0x50, 0xcd, 0x8e, 0x60, 0x2a, 0x08, 0x2a, 0x9b, 0xc4, 0x06, 0x36, 0xcc, 0x18, 0x10,
0x00, 0x00, 0xff, 0xff, 0x2c, 0x89, 0x1f, 0x45, 0x7a, 0x00, 0x00, 0x00,
}
我希望生成的 go 代码使用正确的包名相互导入,以便
book.pb.go
会这样开始:package book
import (
fmt "fmt"
math "math"
proto "github.com/golang/protobuf/proto"
author "github.com/kurtpeek/proto-example/gen/go/author"
)
如何让 Protobuf 编译器“知道”生成代码所在的 Go 模块?
(我怀疑我需要指定
option go_package
(参见 https://developers.google.com/protocol-buffers/docs/gotutorial),但这样做似乎不会改变生成的代码)。
最佳答案
您快到了!我怀疑你可能会被相对路径咬伤......
如果您的 proto 文件以这样的开头:
package author;
option go_package = "github.com/kurtpeek/proto-example/gen/go/author";
和
package book;
import "author/author.proto";
option go_package = "github.com/kurtpeek/proto-example/gen/go/book";
并使用构建命令(带有相对路径)
mkdir -p gen/go
protoc book/book.proto --go_out=gen/go
protoc author/author.proto --go_out=gen/go
您生成的代码将出现在这些 相对 路径(到您的 CWD):
gen/go/github.com/kurtpeek/proto-example/gen/go/author/author.pb.go
gen/go/github.com/kurtpeek/proto-example/gen/go/book/book.pb.go
生成的
book
包应该具有所需的导入:package book
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
author "github.com/kurtpeek/proto-example/gen/go/author"
math "math"
)
如果您希望将生成的代码放在特定目录中,请使用绝对路径:
mkdir -p /some/absolute/path
protoc my.proto --go_out=/some/absolute/path
关于go - Go 结构的 Protobuf 编译器没有为导入生成正确的包名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60532407/