このページでは、マクロとルールを使用して 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
スタイルガイドに沿って作成します。コードをテストします。
ユーザーをサポートするドキュメントを生成します。
コードのパフォーマンスを最適化する。
拡張機能を他のユーザーにデプロイする。