go mod tidy报错找不到Bazel生成的Protobuf包,如何解决?
解决Bazel生成Go Proto库与Go模块、IDE兼容问题
问题根源
Go模块系统(go mod)和Bazel构建模型相互独立:Bazel默认在沙箱中生成Go proto代码,不会同步到Go模块的源码目录,导致go mod无法解析导入路径,无Bazel插件的IDE也找不到对应的代码文件。
解决方案
方案1:通过go.mod replace指令映射本地路径
在项目根目录的go.mod中添加replace规则,将导入路径指向本地的proto目录:
replace github.com/acme/icoyote/proto => ./icoyote/proto
完成后执行以下操作:
- 运行
bazel build //icoyote/proto:proto_go_proto生成Go proto代码 - 将Bazel生成的代码(默认在
bazel-bin/icoyote/proto/目录下,文件名类似events_go_proto.go)复制到./icoyote/proto/目录中 - 再次执行
go mod tidy即可正常解析
方案2:配置Gazelle自动生成代码到源码目录
修改项目根目录的BUILD.bazel,添加Gazelle配置让其直接调用protoc生成Go代码到本地源码目录:
load("@bazel_gazelle//:def.bzl", "gazelle") gazelle( name = "gazelle", args = [ "go", "proto", "--go_generate_protoc", ], )
同时在icoyote/proto/BUILD.bazel中添加proto包的go_package配置:
gazelle:proto go_package github.com/acme/icoyote/proto
运行bazel run //:gazelle重新生成构建规则,Gazelle会自动将Go proto代码生成到./icoyote/proto/目录下。此时Go模块和IDE都能直接识别这些代码,go mod tidy也不会再报错。
方案3:调整go_library规则使用本地生成的代码
如果已经手动或通过Gazelle生成了本地的Go proto代码,可以修改icoyote/proto/BUILD.bazel中的go_library规则,直接引用本地的.go文件而非依赖go_proto_library的嵌入:
go_library( name = "proto", srcs = ["events_go_proto.go"], importpath = "github.com/acme/icoyote/proto", visibility = ["//visibility:public"], deps = ["@com_google_googleapis//google/api:annotations_go_proto"], )
这种方式让Bazel直接使用本地源码,同时Go模块和IDE也能正常识别。
内容的提问来源于stack exchange,提问作者Paul Milovanov
相关产品推荐
相关产品推荐

