Bazel构建Go项目go_embed_data报could not embed错误如何解决
报错原因
Bazel编译时采用隔离沙箱环境,默认只会将BUILD文件中显式声明的资源放入沙箱,你代码中//go:embed引用的static目录未在Go编译规则中声明,因此沙箱中找不到对应文件触发报错。
原生go build会扫描当前工作目录下的所有匹配文件,因此可以正常编译。
解决方案1:使用rules_go原生embed支持(更推荐)
rules_go从v0.29.0版本开始原生支持Go标准库embed,无需额外引入go_embed_data,适配性更强,还能兼容你现有代码不需要修改main.go:
- 删除原有
go_embed_data定义的static_files目标 - 修改
go_library配置,添加embedsrcs字段声明要嵌入的静态资源:
go_library( name = "kmdr_lib", srcs = ["main.go"], embedsrcs = glob(["static/**/*"]), # gazelle:keep importpath = "github.com/myorg/myrepo", visibility = ["//visibility:private"], deps = [ "//api", "//cmd", ], )
- (可选)如果希望Gazelle自动识别embed标签生成对应配置,可在BUILD文件顶部添加注释
# gazelle:embed **/*,Gazelle运行时会自动扫描//go:embed指令,将匹配的资源自动加入embedsrcs,不需要手动维护。
解决方案2:保留go_embed_data的修复方式
如果你要继续使用go_embed_data,需要修正两个错误点:
- 移除
main.go中你自己定义的//go:embed static/*和var staticFS embed.FS代码,因为go_embed_data已经自动生成了同名同包的变量,重复定义会触发编译错误。 - 在
srcs中添加的:static_files后加# gazelle:keep注释,告知Gazelle不要删除该自定义依赖:
go_library( name = "kmdr_lib", srcs = [ "main.go", ":static_files", # gazelle:keep ], importpath = "github.com/myorg/myrepo", visibility = ["//visibility:private"], deps = [ "//api", "//cmd", ], )
修改完成后重新运行bazel run //:gazelle && bazel build //...即可正常编译。
内容的提问来源于stack exchange,提问作者a11hard
相关产品推荐
相关产品推荐

