「Make」変数は、「Make 変数の置換の対象」としてマークされた属性で使用できる、特別なクラスの展開可能な文字列変数です。
これらは、たとえば、特定のツールチェーン パスをユーザーが作成したビルド アクションに挿入するために使用できます。
Bazel には、すべてのターゲットで使用できる事前定義変数と、依存関係ターゲットで定義され、それらに依存するターゲットでのみ使用できるカスタム変数の両方が用意されています。
「Make」という用語が使われているのは、歴史的な理由によります。これらの変数の構文とセマンティクスは、元々 GNU Make と一致するように設計されていました。
使用
「Subject to 'Make variable' substitution」とマークされた属性は、次のように「Make」変数 FOO
を参照できます。
my_attr = "prefix $(FOO) suffix"
つまり、$(FOO)
に一致する部分文字列は FOO
の値に展開されます。この値が "bar"
の場合、最終的な文字列は次のようになります。
my_attr = "prefix bar suffix"
FOO
が使用側のターゲットに認識されている変数に対応していない場合、Bazel はエラーで失敗します。
名前が @
などの文字以外の記号である「Make」変数も、かっこなしでドル記号のみを使用して参照できます。次に例を示します。
my_attr = "prefix $@ suffix"
$
を文字列リテラルとして書き込む(つまり、変数の展開を防ぐ)には、$$
と記述します。
事前定義された変数
事前定義された「Make」変数は、任意のターゲットで 「Make 変数の置換の対象」とマークされた任意の属性で参照できます。
特定のビルド オプションのセットに対するこれらの変数とその値のリストを表示するには、次のコマンドを実行します。
bazel info --show_make_env [build options]
大文字で始まる出力行を確認します。
ツールチェーン オプション変数
COMPILATION_MODE
:fastbuild
、dbg
、またはopt
。(詳細)
パス変数
-
BINDIR
: ターゲット アーキテクチャ用に生成されたバイナリ ツリーのベース。クロス コンパイルをサポートするため、ホスト アーキテクチャでビルド中に実行されるプログラムには別のツリーが使用されることがあります。
genrule
内からツールを実行する場合は、$(execpath toolname)
でパスを取得することをおすすめします。ここで、toolname はgenrule
のtools
属性にリストされている必要があります。 GENDIR
: ターゲット アーキテクチャ用に生成されたコードツリーのベース。
マシン アーキテクチャ変数
-
TARGET_CPU
: ターゲット アーキテクチャの CPU(k8
など)。
事前定義された genrule 変数
以下は、genrule
の cmd
属性に特に使用可能であり、通常、その属性を機能させるために重要です。
OUTS
:genrule
のouts
リスト。出力ファイルが 1 つしかない場合は、$@
を使用することもできます。-
SRCS
:genrule
のsrcs
リスト(より正確には、srcs
リスト内のラベルに対応するファイルのパス名)。ソースファイルが 1 つしかない場合は、$<
を使用することもできます。 -
<
:SRCS
(単一ファイルの場合)。それ以外の場合は、ビルドエラーがトリガーされます。 -
@
:OUTS
(単一ファイルの場合)。それ以外の場合は、ビルドエラーがトリガーされます。 -
RULEDIR
: ターゲットの出力ディレクトリ。つまり、genfiles
またはbin
ツリーの下にあるターゲットを含むパッケージの名前に対応するディレクトリ。//my/pkg:my_genrule
の出力がサブディレクトリにある場合でも、//my/pkg:my_genrule
は常にmy/pkg
で終わります。 -
@D
: 出力ディレクトリ。outs にエントリが 1 つある場合、このエントリは、そのファイルを含むディレクトリに展開されます。複数のエントリがある場合、すべての出力ファイルが同じサブディレクトリにある場合でも、genfiles
ツリー内のパッケージのルート ディレクトリに展開されます。注:
RULEDIR
はセマンティクスが単純で、出力ファイルの数に関係なく同じように動作するため、@D
よりもRULEDIR
を使用してください。genrule で一時的な中間ファイルを生成する必要がある場合(コンパイラなどの他のツールを使用した結果など)、
@D
への書き込みを試み(/tmp
も書き込み可能ですが)、完了前に削除する必要があります。特に、入力を含むディレクトリへの書き込みは避けてください。読み取り専用ファイル システムに存在する場合もあります。そうでない場合でも、そうするとソースツリーが破棄されます。
事前定義されたソースパス変数と出力パス変数
事前定義された変数 execpath
、execpaths
、rootpath
、rootpaths
、location
、locations
は、ラベル パラメータ($(execpath
//foo:bar)
など)を受け取り、そのラベルで示されたファイルパスを置き換えます。
ソースファイルの場合、これはワークスペースのルートからの相対パスです。ルール出力のファイルの場合、これはファイルの出力パスです(以下の出力ファイルの説明を参照)。
-
execpath
: Bazel がビルド アクションを実行する execroot の下のパスを示します。上記の例では、Bazel はワークスペース ルートの
bazel-myproject
シンボリック リンクでリンクされたディレクトリ内のすべてのビルド アクションを実行します。ソースファイルempty.source
はパスbazel-myproject/testapp/empty.source
にリンクされています。したがって、実行パス(ルートの下のサブパス)はtestapp/empty.source
です。これは、ビルド アクションがファイルを見つけるために使用できるパスです。出力ファイルも同様にステージングされますが、サブパス
bazel-out/cpu-compilation_mode/bin
(ツールの出力の場合はbazel-out/cpu-opt-exec-hash/bin
)も接頭辞として付加されます。上記の例では、//testapp:app
はshow_app_output
のtools
属性に表示されるため、ツールです。したがって、出力ファイルapp
はbazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app
に書き込まれます。したがって、実行パスはbazel-out/cpu-opt-exec-hash/bin/testapp/app
です。この余分な接頭辞により、同じビルド内で、たとえば 2 つの異なる CPU に対して同じターゲットをビルドしても、結果が互いに上書きされることはありません。この変数に渡されるラベルは、1 つのファイルを表す必要があります。ソースファイルを表すラベルの場合、これは自動的に true になります。ルールを表すラベルの場合、ルールは 1 つの出力を生成する必要があります。これが false であるか、ラベルの形式が正しくない場合、ビルドはエラーで失敗します。
-
rootpath
: ビルドされたバイナリが、メイン リポジトリに対応する runfiles ディレクトリのサブディレクトリを基準として、実行時に依存関係を見つけるために使用できるパスを示します。注: これは、--enable_runfiles
が有効になっている場合にのみ機能します。Windows ではデフォルトで有効になっていません。クロスプラットフォームのサポートには、代わりにrlocationpath
を使用します。これは
execpath
と似ていますが、上記の構成接頭辞が削除されます。上記の例では、empty.source
とapp
の両方が純粋なワークスペース相対パス(testapp/empty.source
とtestapp/app
)を使用していることを意味します。外部リポジトリ
repo
内のファイルのrootpath
は、../repo/
で始まり、その後にリポジトリ相対パスが続きます。これは、
execpath
と同じ「出力は 1 つのみ」という要件を満たしています。 -
rlocationpath
: ビルドされたバイナリが runfiles ライブラリのRlocation
関数に渡して、実行時に依存関係を見つけることができるパス。runfiles ディレクトリ(使用可能な場合)または runfiles マニフェストを使用します。これは
rootpath
と同様に構成接頭辞を含みませんが、常にリポジトリの名前で始まる点が異なります。上記の例では、empty.source
とapp
はmyproject/testapp/empty.source
とmyproject/testapp/app
のパスになります。外部リポジトリ
repo
内のファイルのrlocationpath
は、repo/
で始まり、その後にリポジトリ相対パスが続きます。このパスをバイナリに渡し、runfiles ライブラリを使用してファイル システム パスに解決する方法は、実行時に依存関係を見つけるための推奨アプローチです。
rootpath
と比較すると、すべてのプラットフォームで動作し、実行ファイル ディレクトリが使用できない場合でも動作するという利点があります。これは、
execpath
と同じ「出力は 1 つのみ」という要件を満たしています。 -
location
: 展開される属性に応じて、execpath
またはrootpath
のいずれかの類義語。これは Starlark 以前の動作であり、特定のルールで何が行われるかを十分に理解していない限り、おすすめしません。詳しくは、#2475 をご覧ください。
execpaths
、rootpaths
、rlocationpaths
、locations
は、それぞれ execpath
、rootpath
、rlocationpaths
、location
の複数形です。複数の出力を生成するラベルをサポートしています。この場合、各出力はスペースで区切って一覧表示されます。出力がゼロのルールと形式が正しくないラベルは、ビルドエラーを生成します。
参照されるすべてのラベルは、使用側のターゲットの srcs
、出力ファイル、または deps
に表示される必要があります。そうしないと、ビルドは失敗します。C++ ターゲットは data
のラベルを参照することもできます。
ラベルは正規形である必要はありません。foo
、:foo
、//somepkg:foo
のいずれでも構いません。
カスタム変数
カスタムの「Make」変数は、「Make 変数の置換の対象」としてマークされた任意の属性で参照できますが、これらの変数を定義する他のターゲットに依存するターゲットでのみ参照できます。
コア Bazel に組み込む正当な理由がない限り、すべての変数はカスタムにするのがベスト プラクティスです。これにより、Bazel は、ターゲットが気にしない可能性のある変数を供給するために、コストのかかる依存関係を読み込む必要がなくなります。
C++ ツールチェーン変数
次のものは C++ ツールチェーン ルールで定義され、toolchains =
["@bazel_tools//tools/cpp:current_cc_toolchain"]
を設定するルールで使用できます。java_binary
などの一部のルールでは、ルール定義に C++ ツールチェーンが暗黙的に含まれています。これらの変数は自動的に継承されます。
組み込みの C++ ルールは、「コンパイラを実行する」よりもはるかに高度です。*SAN、ThinLTO、モジュールあり/なし、慎重に最適化されたバイナリなどの多様なコンパイル モードをサポートすると同時に、複数のプラットフォームで高速実行テストを行うために、組み込みルールは、内部で生成される可能性のある複数のアクションそれぞれに正しい入力、出力、コマンドライン フラグが設定されるように、細心の注意を払っています。
これらの変数は、言語の専門家がまれに使用するフォールバック メカニズムです。使用したくなった場合は、まず Bazel デベロッパーにお問い合わせください。
ABI
: C++ ABI バージョン。-
AR
: クロスツールの「ar」コマンド。 -
C_COMPILER
: C/C++ コンパイラの識別子(例:llvm
)。 -
CC
: C および C++ コンパイラ コマンド。CC_FLAGS
は常にCC
と組み合わせて使用することを強くおすすめします。これを行わない場合は、自己責任となります。 CC_FLAGS
: genrule で使用可能な C/C++ コンパイラの最小限のフラグセット。特に、CC
が複数のアーキテクチャをサポートしている場合に、正しいアーキテクチャを選択するためのフラグが含まれています。-
NM
: crosstool の「nm」コマンド。 -
OBJCOPY
: C/C++ コンパイラと同じスイートの objcopy コマンド。 -
STRIP
: C/C++ コンパイラと同じスイートの strip コマンド。
Java ツールチェーン変数
以下は Java ツールチェーン ルールで定義され、toolchains =
["@bazel_tools//tools/jdk:current_java_runtime"]
(またはホスト ツールチェーンの同等の "@bazel_tools//tools/jdk:current_host_java_runtime"
)を設定するルールで使用できます。
JDK のツールのほとんどは直接使用しないでください。組み込みの Java ルールでは、インターフェース Jar、ヘッダー インターフェース Jar、高度に最適化された Jar パッケージングとマージの実装など、アップストリーム ツールで表現できるよりもはるかに高度なアプローチが Java のコンパイルとパッケージングに使用されています。
これらの変数は、言語の専門家がまれに使用するフォールバック メカニズムです。使用したくなった場合は、まず Bazel デベロッパーにお問い合わせください。
-
JAVA
: 「java」コマンド(Java 仮想マシン)。これを避け、可能であれば代わりにjava_binary
ルールを使用してください。相対パスにすることもできます。java
を呼び出す前にディレクトリを変更する必要がある場合は、変更する前に作業ディレクトリをキャプチャする必要があります。 JAVABASE
: Java ユーティリティを含むベース ディレクトリ。相対パスにすることもできます。「bin」サブディレクトリがあります。
Starlark で定義された変数
ルールとツールチェーンの作成者は、TemplateVariableInfo プロバイダを返すことで、完全にカスタムの変数を定義できます。toolchains
属性を介してこれらに依存するルールは、それらの値を読み取ることができます。