bazelでWORKSPACEにGo言語のライブラリを追加する楽なやり方
Go言語のプロジェクトをビルドシステムbazelを用いて管理しているとする。そのとき、新しくライブラリの依存を追加する場合のやりかた
困ること
bazelはプロジェクトで使うパッケージはbazel自身が取ってくる。つまり、Goのパッケージ管理システムを使わない。
そbazelはgit_repository
もしくは http_archive
で取得したディレクトリ( goの場合は go_repositoryも)に
ひとつのプロジェクト(e.g. github.com/keizo042/go-something )として扱い、それぞれのディレクトリには使いたいプロジェクトにつけた名前(e.g. com_github_keizo042_go_something)からの絶対パス ( "//utils"_を用いて依存関係を一意にする。
これで何がおこるかというと、bazelが依存したライブラリを見つけられずにビルドが失敗する。 そしてその依存関係を解決を手で記述するのがめんくさいため、なるべくコマンドに自動生成してもらうやり方を書いた。
使うもの
- bazel
- gazelle
- Go言語のパッケージ管理システム(ここではGo Moduleを例に使う)
やりかた
1. Go言語のソースコードに新しく依存したいパッケージを追加する
package sample import ( "github.com/keizo042/go-something/utils" )
2. Go言語のパッケージ管理システムを使い依存関係ファイルを作る
Go111MODULE=on go mod init && go mod tidy
3. gazelle を持ちいて依存関係ファイルからWORKSPACEとBUILD.bazelを生成する
bazel run //:gazelle update-repo -- -from_file=go.mod
4. だいたいこんな感じになる
WORKSPACE
go_repository( importpath = "github.com/keizo042/go-something", name = "com_github_keizo042_go_something" tags = "v1.0.0", )
BUILD.bazel
go_package( deps = [ "com_github_keizo042_go_something//utils", ] )
なんでこうするのか
bazelのGo言語サポート用コマンドgazelleには、Go言語のパッケージマネージャの依存関係ファイルからWORKSPACEを自動生成する機能がついている。 そのため、Go Module or depに依存関係の解析をさせたのち、gazelle update-repo コマンドでその結果を取り込むことができる。 こうすれば、自分でファイルを書き換えずに依存関係を解決できる。
さらに、gazelle updateでWORKSPACE以下のGo言語のファイルからimportしているライブラリを読み取ってWORKSPACEにあるパッケージ照らし合わせてBUILD.bazelを更新することもできる。 bazel管理のプロジェクトにおいて、 ライブラリを追加した後、
GO111MODULE=on go mod init && go mod tidy && bazel run //:gazelle update-repos -- -from_file=go.mod && bazel run //:gazelle update
としておくといい感じにライブラリの依存関係を管理できる。