「Bazel、Gazelle、bzlmod を使用したモノレポでの Go による構築」に関する投稿を書き、何人かの同僚と共有した後、モノリポ開発への関心が高まっていることに気づきました。それがもたらすメリットを理解できるほど経験を積んでいる人がまだ多くないことを知りました。そこで、Bazel と Go lang を使用したシンプルな hello world プログラムに関するこの投稿から、これをシリーズに変換することにしました
この投稿では、コード スニペットとともに Bazel の非常に基本的な概念をいくつか取り上げ、すぐに使い始められるようにしていきます。
公式ドキュメントによると
Bazel は、Make、Maven、Gradle に似たオープンソースのビルドおよびテスト ツールです。人間が読める高レベルのビルド言語を使用します。 Bazel は複数の言語でプロジェクトをサポートし、複数のプラットフォーム用の出力を構築します。 Bazel は、複数のリポジトリにわたる大規模なコードベースと多数のユーザーをサポートします。
Google では何十年にもわたって使用されており、徹底的な実戦テストが行われています。私がこれに気づいた経緯については、上にリンクされた投稿をご覧ください。
このシリーズの目的のために、時間の経過とともに進化するリポジトリを github.com/nixclix/basil に作成しました。この記事の執筆時点での最新のコミットは https://github.com/nixclix/basil/tree/d8af2aea6fb8b692f735f9959429df9fcd28422b
それでは、選択したいプロバイダーで新しい git リポジトリを作成してください
.gitignore については、コミットに不要なファイルが含まれないように、以下を追加することを強くお勧めします
# If you prefer the allow list template instead of the deny list, see community template: # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # bazel-* /.ijwb /.clwb /.idea /.project *.swp /.bazelrc.user # macOS-specific excludes .DS_Store # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, built with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Dependency directories (remove the comment below to include it) # vendor/ # Go workspace file go.work go.work.sum # env file .env
Bazel 6.3 を開始すると、WORKSPACE ファイルは必要なくなります。したがって、リポジトリのルートに以下を作成することから始めます
MODULE.bazel
"""Building go applications in a monorepo environment""" module(name = "basil", version = "0.0.0") http_file = use_repo_rule( "@bazel_tools//tools/build_defs/repo:http.bzl", "http_file" ) http_archive = use_repo_rule( "@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive" ) # https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/bzlmod.md bazel_dep(name = "rules_go", version = "0.50.1") bazel_dep(name = "gazelle", version = "0.39.1") GO_VERSION = "1.23.2" go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk.download(version = GO_VERSION) go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod")
ここで、使用する go のバージョンと、gazelle および rules_go のバージョンを設定します。
BUILD ファイル管理には Gazelle を使用します。 Gazelle を使用すると、ビルド ファイルの生成が非常に便利になります。詳細については、こちらをご覧ください
BUILD.bazel
load("@gazelle//:def.bzl", "gazelle") gazelle(name = "gazelle") gazelle( name = "gazelle-update-repos", args = [ "-from_file=go.mod", "-to_macro=deps.bzl%go_dependencies", "-prune", ], command = "update-repos", )
これはリポジトリのルートにある必要があります。これにより、go mod ファイルのソースとその他のプロセスを実行するようガゼルに指示されます
次に、それぞれの内容を含むさらに 3 つのファイルを作成します。現時点では、これらが何をするかについては心配しないでください。
.bazelignore
runfiles/ bzlmod/
.bazelrc
# Enable Bzlmod for every Bazel command common --enable_bzlmod
.bazelversion
# If you prefer the allow list template instead of the deny list, see community template: # https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore # bazel-* /.ijwb /.clwb /.idea /.project *.swp /.bazelrc.user # macOS-specific excludes .DS_Store # Binaries for programs and plugins *.exe *.exe~ *.dll *.so *.dylib # Test binary, built with `go test -c` *.test # Output of the go coverage tool, specifically when used with LiteIDE *.out # Dependency directories (remove the comment below to include it) # vendor/ # Go workspace file go.work go.work.sum # env file .env
わかりました。この時点までに、基本的な機能を実行するために必要なものはすべて揃っているはずです。ここで、ルートで bazel build //... を実行すると、bazel はリポジトリを横断して、検出したパッケージをビルドできるようになります。 Bazel は以前のビルドからのパッケージ出力をキャッシュするため、これ以降のビルドは非常に高速になるはずです。
コードの基本的な構成として、すべての Go コードを /packages というディレクトリに記述します。こうすることで、コードの他の部分の参照は //packages/...
として参照できます。パッケージディレクトリに helloworld という名前のディレクトリを作成し、次の内容を追加しましょう
helloworld.go
"""Building go applications in a monorepo environment""" module(name = "basil", version = "0.0.0") http_file = use_repo_rule( "@bazel_tools//tools/build_defs/repo:http.bzl", "http_file" ) http_archive = use_repo_rule( "@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive" ) # https://github.com/bazelbuild/rules_go/blob/master/docs/go/core/bzlmod.md bazel_dep(name = "rules_go", version = "0.50.1") bazel_dep(name = "gazelle", version = "0.39.1") GO_VERSION = "1.23.2" go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") go_sdk.download(version = GO_VERSION) go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps") go_deps.from_file(go_mod = "//:go.mod")
BUILD.bazel
load("@gazelle//:def.bzl", "gazelle") gazelle(name = "gazelle") gazelle( name = "gazelle-update-repos", args = [ "-from_file=go.mod", "-to_macro=deps.bzl%go_dependencies", "-prune", ], command = "update-repos", )
go プログラムは非常に単純です。 hello world メッセージを単純に出力する単純な main 関数があります。
私たちが興味があるのは、BUILD.bazel ファイルです。このブロックごとに見て、その意味を理解してみましょう。
最初の行は、 rules_go から go_binary マクロと go_library マクロをロードします。これらはコードの後半で使用されていることがわかります。
10 行目では、helloworld_lib というライブラリを定義し、ライブラリのソースを helloworld.go として指定しています。このパッケージをインポート可能にする必要がある場合は、basil/packages/helloworld_lib で使用できるパスを指定することもできます。次に可視性が登場します。ここでは、ライブラリがこのパッケージ内でのみ表示されるプライベートであることを指定しています。今後の投稿では、他のパッケージからの依存関係を使用するためにこれらのパラメーターを変更する方法を検討する可能性があります。
3 行目では、rules_go の go_binary マクロを使用して、プログラム用のバイナリを生成します。ここでは、埋め込みパラメーターで前に定義したライブラリを指定します。パッケージの可視性はバイナリにも適用されます。
それで終わりです。出来上がり!最初に bazel build //packages/helloworld を使用してビルドし、続いて bazel run //packages/helloworld
を使用してバイナリを実行できます。この投稿が気に入って、シリーズの一部としてこれに基づく今後の投稿を希望される場合は、この投稿を購読して共有してください。
以上がBazel と Go lang を使用した単純な hello world プログラムの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。