背景
Bazelで依存関係を管理している環境で、celライブラリを導入したところ次のようなエラーが発生しました。
'@com_github_google_cel_go//cel:cel': target 'cel' not declared in package 'cel' defined by /external/com_github_google_cel_go/cel/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/celext:celext' '@com_github_google_cel_go//common/overloads:overloads': target 'overloads' not declared in package 'common/overloads' defined by /external/com_github_google_cel_go/common/overloads/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/celext:celext' '@com_github_google_cel_go//common/types:types': target 'types' not declared in package 'common/types' defined by /external/com_github_google_cel_go/common/types/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/celext:celext' '@com_github_google_cel_go//common/types/ref:ref': target 'ref' not declared in package 'common/types/ref' defined by /external/com_github_google_cel_go/common/types/ref/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/celext:celext' '@com_github_google_cel_go//common/types/traits:traits': target 'traits' not declared in package 'common/types/traits' defined by /external/com_github_google_cel_go/common/types/traits/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/celext:celext' '@com_github_google_cel_go//ext:ext': target 'ext' not declared in package 'ext' defined by /external/com_github_google_cel_go/ext/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/celext:celext' '@com_github_google_cel_go//cel:cel': target 'cel' not declared in package 'cel' defined by /external/com_github_google_cel_go/cel/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/expression:expression' '@com_github_google_cel_go//interpreter:interpreter': target 'interpreter' not declared in package 'interpreter' defined by /external/com_github_google_cel_go/interpreter/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/expression:expression' '@com_github_google_cel_go//cel:cel': target 'cel' not declared in package 'cel' defined by /external/com_github_google_cel_go/cel/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/constraints:constraints' '@com_github_google_cel_go//cel:cel': target 'cel' not declared in package 'cel' defined by /external/com_github_google_cel_go/cel/BUILD.bazel and referenced by '@com_github_bufbuild_protovalidate_go//internal/evaluator:evaluator'
これはcel-goに依存していた場合のBazelのターゲットの記述が本来は
go_library(
...
deps = [
...
"@com_github_google_cel_go//cel:go_default_library",
...
],
)
であるべきが、gazelleを使ったところ
go_library(
...
deps = [
...
"@com_github_google_cel_go//cel",
...
],
)
となってターゲットの記述が不適切になってしまったせいです。
今回はこの回避策方法について説明します。
環境
- Bazel v6.5.0
- bazel-gazelle v0.35.0
原因詳細
cel-goはBazelを使っており、中でBUILD.bazelを持っています。
go_library(
name = "go_default_library",
srcs = [
"cel.go",
"decls.go",
"env.go",
"folding.go",
"io.go",
"inlining.go",
"library.go",
"macro.go",
"optimizer.go",
"options.go",
"program.go",
"validator.go",
],
importpath = "github.com/google/cel-go/cel",
...
従ってこれに依存する場合、Bazelのターゲット名はgithub.com/google/cel-go/cel:go_default_libraryとなります。
しかしGoの一般的なライブラリはBazelを使っておらず、gazelleがそれを考慮してくれないため
"@com_github_google_cel_go//cel",
"@com_github_google_uuid//:uuid",
のように処理してしまうのが原因です。
対応方法
2つの方法を紹介します。
方法1:手動でターゲット名を設定してkeepを付ける
gazelleは# keepがあればそこを変更しないので、
go_library(
....
deps = [
...
"@com_github_google_cel_go//cel:go_default_library", # keep
...
],
)
や
# keep go_library( .... deps = [ ... "@com_github_google_cel_go//cel:go_default_library", ... ], )
といった記述にすることでターゲット名であるgo_default_libraryが削られるのを防げます。
しかしこれは
- 前者であればcel-goの別pkgが必要となったときに都度対応が必要になる
- 後者であれば他の依存ライブラリがgazelleで更新されなくなる
といった課題がありあまりよくありません。
方法2:deps.bzlを編集する
cel-goのdeps.bzlは次のようになっていますが、
go_repository(
name = "com_github_google_cel_go",
build_file_proto_mode = "disable_global",
importpath = "github.com/google/cel-go",
sum = "h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=",
version = "v0.20.1",
)
これにbuild_naming_conventionを付けます。
go_repository(
name = "com_github_google_cel_go",
build_file_proto_mode = "disable_global",
build_naming_convention = "go_default_library", # ここ
importpath = "github.com/google/cel-go",
sum = "h1:nDx9r8S3L4pE61eDdt8igGj8rf5kjYR3ILxWIpWNi84=",
version = "v0.20.1",
)
こうするとgazelleが解釈してくれて、BUILD.bazelも"@com_github_google_cel_go//cel:go_default_library"となってくれます。
まとめ
Bazelを使っているライブラリに依存していた場合、ターゲット名がうまく解釈されない場合の対応方法を紹介しました。