このページでは、マクロとルールを使用して BUILD 言語を拡張する方法について説明します。
Bazel 拡張機能は、.bzl
で終わるファイルです。拡張機能からシンボルをインポートするには、load ステートメントを使用します。
高度なコンセプトを学ぶ前に、まず次のことを行います。
BUILD
ファイルと.bzl
ファイルの両方で使用される Starlark 言語について確認する。2 つの
BUILD
ファイル間で変数を共有する方法について説明します。
マクロとルール
マクロは、ルールをインスタンス化する関数です。マクロには、シンボリック マクロ(Bazel 8 で新しく追加)と以前のマクロの 2 種類があります。2 つのマクロは定義が異なりますが、ユーザーの視点から見ると動作はほぼ同じです。マクロは、BUILD
ファイルが繰り返しだらけになったり、複雑になりすぎたりした場合に、コードの一部を再利用できるため便利です。この関数は、BUILD
ファイルが読み取られるとすぐに評価されます。BUILD
ファイルの評価後、Bazel はマクロに関する情報をほとんど持っていません。マクロが genrule
を生成する場合、Bazel は、BUILD
ファイルで genrule
を宣言したかのように動作します。(ただし、シンボリック マクロで宣言されたターゲットには特別な可視性セマンティクスがあります。シンボリック マクロは、パッケージの他の部分から内部ターゲットを隠すことができます)。
ルールはマクロよりも強力です。Bazel の内部にアクセスして、何が起こっているかを完全に制御できます。たとえば、他のルールに情報を渡すことができます。
単純なロジックを再利用する場合は、マクロから始めます。古い Bazel バージョンをサポートする必要がない限り、シンボリック マクロをおすすめします。マクロが複雑になった場合は、ルールにすることをおすすめします。通常、新しい言語のサポートはルールを使用して行われます。ルールは上級ユーザー向けであり、ほとんどのユーザーはルールを作成する必要はありません。既存のルールを読み込んで呼び出すだけです。
評価モデル
ビルドは 3 つのフェーズで構成されます。
読み込みフェーズ。まず、ビルドに必要なすべての拡張機能とすべての
BUILD
ファイルを読み込んで評価します。BUILD
ファイルの実行は、単にルールをインスタンス化するだけです(ルールが呼び出されるたびに、グラフに追加されます)。マクロはここで評価されます。分析フェーズ。ルールのコード(
implementation
関数)が実行され、アクションがインスタンス化されます。アクションは、「hello.c で gcc を実行して hello.o を取得する」など、一連の入力から一連の出力を生成する方法を記述します。実際のコマンドを実行する前に、生成されるファイルを明示的にリストする必要があります。つまり、分析フェーズでは、読み込みフェーズで生成されたグラフを取得し、アクション グラフを生成します。実行フェーズ。アクションは、出力の少なくとも 1 つが必要な場合に実行されます。ファイルが見つからない場合や、コマンドが 1 つの出力を生成できない場合、ビルドは失敗します。このフェーズではテストも実行されます。
Bazel は並列処理を使用して、.bzl
ファイルと BUILD
ファイルの読み取り、解析、評価を行います。ファイルはビルドごとに最大 1 回読み取られ、評価の結果はキャッシュに保存されて再利用されます。ファイルは、すべての依存関係(load()
ステートメント)が解決された後にのみ評価されます。設計上、.bzl
ファイルの読み込みには目に見える副作用はなく、値と関数のみが定義されます。
Bazel は、依存関係分析を使用して、読み込む必要があるファイル、分析する必要があるルール、実行する必要があるアクションを把握します。たとえば、現在のビルドで必要のないアクションをルールが生成した場合、それらのアクションは実行されません。
拡張機能の作成
一部のコードを再利用するために、最初のマクロを作成します。次に、マクロの詳細と、マクロを使用して「カスタム動詞」を作成する方法について説明します。
独自の拡張機能を作成する際には、以下の 2 つのリンクが非常に役立ちます。手元に置いておきましょう。
さらに詳しく
マクロとルールに加えて、アスペクトとリポジトリルールを記述することもできます。
Buildifier を一貫して使用して、コードのフォーマットと lint を行います。
.bzl
スタイルガイドに沿って作成します。コードをテストします。
ユーザーを支援するドキュメントを生成します。
コードのパフォーマンスを最適化します。
他のユーザーに拡張機能をデプロイします。