Bazelを使ってGoをビルド(その1)

Bazel

メリット

正確性

  • Isolateな環境でBuildを実行する
  • Bazel RuleがInputだけアクセスできる

高速

  • Declarative、そしてBazelが依頼関係を分析できます。変更があったら、影響する部分だけ再Buildすることができます。
  • BazelがPure Functionで、アウトプットがインプットによってのみ決定される
  • インプットによって、Cacheが簡単にできます。そして、並列実行もできます。

多様化

  • Bazelがどの言語・フレームワークでもBuild可
  • つまりサーバーでMaven、クライアントでWebpack/Gulp、モバイルがGradleのような別々なBuildツールがBazelで統一可能

Bazelのまえにgazelle

前提

gazelle

  • rules_goというGo言語向けbazelルールがある
  • gazelleとはrules_goを用いたビルド設定を自動生成するツール
  • rules_dockerは、bazelを用いてdockerイメージをビルドしたり、プッシュすることができるルール

実例

Bazel準備

  • vi WORKSPACE
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# download go bazel tools
http_archive(
    name = "io_bazel_rules_go",
    urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.15.1/rules_go-0.15.1.tar.gz"],
    sha256 = "5f3b0304cdf0c505ec9e5b3c4fc4a87b5ca21b13d8ecc780c97df3d1809b9ce6",
)
# download the gazelle tool
http_archive(
    name = "bazel_gazelle",
    urls = ["https://github.com/bazelbuild/bazel-gazelle/releases/download/0.14.0/bazel-gazelle-0.14.0.tar.gz"],
    sha256 = "c0a5739d12c6d05b6c1ad56f2200cb0b57c5a70e03ebd2f7b87ce88cabf09c7b",
)

# load go rules
load("@io_bazel_rules_go//go:def.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()

# load gazelle
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
gazelle_dependencies()


# external dependencies
load("@bazel_gazelle//:deps.bzl", "go_repository")

go_repository(
    name = "com_github_golang_protobuf",
    importpath = "github.com/golang/protobuf",
    tag = "v1.14.0",
)
  • BUILD.bazel
load("@bazel_gazelle//:def.bzl", "gazelle")

# gazelle:prefix google.golang.org/grpc/examples/helloworld
gazelle(name = "gazelle")
  • gazelle実行
bazel run //:gazelle
  • これをやると、たとえばhoge_serverとhoge_clientとプロジェクトが別れている場合でも、それぞれbazelができる
  • その中で以下のようにコマンド打つだけでそれぞれBuildできる
  • bazelがあれば、ビルド時のコマンドや構成が異なるプロジェクトでも一環したコマンドでできる
  • しかもはやい
$ bazel build //hoge_server
$ bazel build //hoge_client