変数を作成する

「Make」変数は、 「Make 変数の置換の対象」としてマークされた属性で使用できる、特別なクラスの展開可能な文字列変数です。

たとえば、これを使用して、特定のツールチェーン パスを ユーザーが作成したビルド アクションに挿入できます。

Bazel には、すべての ターゲットで使用できる事前定義変数と、依存関係ターゲット で定義され、それらに依存するターゲットでのみ使用できるカスタム変数の両方が用意されています。

「Make」という用語の理由は歴史的なものです。これらの変数の構文とセマンティクスは、元々 GNU Makeと一致するように設計されていました。

次のコマンドを実行します。

_「Make 変数の置換の対象」_としてマークされた属性は、次のように「Make」変数 FOO を参照できます。

my_attr = "prefix $(FOO) suffix"

つまり、$(FOO) に一致するサブストリングは FOO の値に展開されます。その値が "bar" の場合、最終的な文字列は次のようになります。

my_attr = "prefix bar suffix"

FOO が使用側のターゲットに認識されている変数に対応していない場合、Bazel はエラーで失敗します。

名前が @ などの文字以外の記号である「Make」変数は、かっこなしで ドル記号のみを使用して参照することもできます。次に例を示します。

my_attr = "prefix $@ suffix"

$ を文字列リテラルとして記述するには(つまり、変数 の展開を防ぐため)、$$.

Predefined variables

Predefined "Make" variables can be referenced by any attribute marked as "Subject to 'Make variable' substitution" on any target.

To see the list of these variables and their values for a given set of build options, run

bazel info --show_make_env [build options]

and look at the top output lines with capital letters.

See an example of predefined variables.

Toolchain option variables

Path variables

  • BINDIR: The base of the generated binary tree for the target architecture.

    Note that a different tree may be used for programs that run during the build on the host architecture, to support cross-compiling.

    If you want to run a tool from within a genrule, the recommended way to get its path is $(execpath toolname), where toolname must be listed in the genrule's tools attribute.

  • GENDIR: The base of the generated code tree for the target architecture.

Machine architecture variables

  • TARGET_CPU: The target architecture's CPU, e.g. k8.

Predefined genrule variables

The following are specially available to genrule's cmd attribute and are generally important for making that attribute work.

See an example of predefined genrule variables.

  • OUTS: The genrule's outs list. If you have only one output file, you can also use $@.
  • SRCS: The genrule's srcs list (or more precisely: the path names of the files corresponding to labels in the srcs list). If you have only one source file, you can also use $<.
  • <: SRCS, if it is a single file. Else triggers a build error.
  • @: OUTS, if it is a single file. Else triggers a build error.
  • RULEDIR: The output directory of the target, that is, the directory corresponding to the name of the package containing the target under the genfiles or bin tree. For //my/pkg:my_genrule this always ends in my/pkg, even if //my/pkg:my_genrule's outputs are in subdirectories.

  • @D: The output directory. If outs has one entry, this expands to the directory containing that file. If it has multiple entries, this expands to the package's root directory in the genfiles tree, even if all output files are in the same subdirectory!

    Note: Use RULEDIR over @D because RULEDIR has simpler semantics and behaves the same way regardless of the number of output files.

    If the genrule needs to generate temporary intermediate files (perhaps as a result of using some other tool like a compiler), it should attempt to write them to @D (although /tmp will also be writable) and remove them before finishing.

    Especially avoid writing to directories containing inputs. They may be on read-only filesystems. Even if not, doing so would trash the source tree.

Note: If the filenames corresponding to the input labels or the output filenames contain spaces, ', or other special characters (or your genrule is part of a Starlark macro which downstream users may invoke on such files), then $(SRCS) and $(OUTS) are not suitable for interpolation into a command line, as they do not have the semantics that "${@}" would in Bash.

One workaround is to convert to a Bash array, with

mapfile SRCS <<< "$$(sed -e 's/ /\\n/g' <<'genrule_srcs_expansion'
$(SRC)
genrule_srcs_expansion
)
と記述し、後続のコマンドラインで $(SRCS) の代わりに "$$\{SRCS[@]}" を使用します。より堅牢なオプションは、代わりに Starlark ルールを記述することです。

事前定義されたソース/出力パス変数

事前定義された変数 execpathexecpathsrootpathrootpathslocation、および 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:appshow_app_output's tools 属性に表示されるため、ツールです。 したがって、その出力ファイル appbazel-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.sourceapp の両方が純粋なワークスペース相対 パス(testapp/empty.sourcetestapp/app)を使用します。

    外部リポジトリ repo 内のファイルの rootpath は、../repo/ で始まり、その後に リポジトリ相対パスが続きます。

    これには、"出力は 1 つのみ" という要件が execpath と同じです。

  • rlocationpath: ビルドされたバイナリが runfiles ライブラリの Rlocation 関数に渡して、実行時に依存関係を見つけることができるパス。runfiles ディレクトリ(使用可能な場合)または runfiles マニフェストを使用します。

    これは、rootpath に似ていますが、構成接頭辞が含まれていないという点で異なります。ただし、常にリポジトリの名前で始まる点が異なります。上記の例では、 empty.sourceapp は、次の パスになります: myproject/testapp/empty.source myproject/testapp/app.

    外部リポジトリ repo 内のファイルの rlocationpath は、repo/ で始まり、その後に リポジトリ相対パスが続きます。

    このパスをバイナリに渡して、runfiles ライブラリを使用してファイル システム パスに解決する方法は、実行時に依存関係を見つけるための推奨される方法です。rootpath と比較して、すべてのプラットフォームで動作し、runfiles ディレクトリが使用できない場合でも動作するという利点があります。

    これには、"出力は 1 つのみ" という要件が execpath と同じです。

  • location: 展開される属性に応じて、execpath または rootpath のいずれかのシノニム。これは Starlark 以前のレガシー動作であり、特定のルールで何を行うかを把握していない限り、おすすめしません。詳細については、#2475 をご覧ください。

execpathsrootpathsrlocationpaths、 、locations は、それぞれ execpath、 、rootpathrlocationpathlocation、 の複数形です。これらは複数の出力を生成するラベルをサポートしています。その場合、 各出力はスペースで区切って一覧表示されます。出力がゼロのルールと形式が正しくない ラベルは、ビルドエラーを生成します。

参照されるラベルはすべて、使用側のターゲットの srcs、 出力ファイル、または deps に表示される必要があります。そうしないと、ビルドは失敗します。C++ ターゲットは data のラベルを参照することもできます。

ラベルは正規フォームである必要はありません。foo:foo および //somepkg:foo はすべて問題ありません。

カスタム変数

カスタムの "Make" 変数は、 "Make 変数の置換の対象" としてマークされた任意の属性で参照できますが、 これらの変数を 定義 する他のターゲットに依存するターゲットでのみ参照できます。

ベスト プラクティスとして、Bazel のコアに組み込む正当な 理由がない限り、すべての変数はカスタムにする必要があります。これにより、Bazel は、ターゲットが気にしない可能性のある変数を供給するために、コストのかかる依存関係を読み込む必要がなくなります。

C++ ツールチェーン変数

以下は C++ ツールチェーン ルールで定義され、 を設定する任意のルールで使用できます。toolchains = ["@bazel_tools//tools/cpp:toolchain_type"] java_binary などの一部のルールでは、ルール定義に C++ ツールチェーンが暗黙的に含まれています。これらの変数は自動的に継承されます。

組み込みの C++ ルールは、「コンパイラを実行する 」よりもはるかに高度です。*SAN、ThinLTO、 モジュールあり/なし、慎重に最適化されたバイナリなど、多様なコンパイル モードをサポートすると同時に、 複数のプラットフォームで高速にテストを実行するために、組み込みルールは、内部的に生成される可能性のある複数のアクションごとに、正しい入力、出力、コマンドライン フラグが設定されるように最大限の努力を払っています。

これらの変数は、言語の専門家がまれに使用するフォールバック メカニズムです。 使用する場合は、まず Bazel デベロッパーにお問い合わせください。

  • ABI: C++ ABI バージョン。
  • AR: crosstool の「ar」コマンド。
  • C_COMPILER: C/C++ コンパイラの識別子(llvm など)。
  • CC: C コンパイラと C++ コンパイラのコマンド。

    CC と組み合わせて CC_FLAGS を常に使用することを強くおすすめします。そうしない場合は、自己責任で行ってください。

  • CC_FLAGS: genrule で使用できる C/C++ コンパイラの最小限のフラグセット。特に、これは 正しいアーキテクチャを選択するためのフラグが含まれています。CC複数の アーキテクチャをサポートしている場合。
  • DUMPBIN:Microsoft Visual Studio の Microsoft COFF Binary File Dumper(dumpbin.exe)。
  • NM: crosstool の「nm」コマンド。
  • OBJCOPY: C/C++ コンパイラと同じスイートの objcopy コマンド。
  • STRIP: C/C++ コンパイラと同じスイートの strip コマンド。

Java ツールチェーン変数

以下は Java ツールチェーン ルールで定義され、 toolchains = ["@rules_java//toolchains:current_java_runtime"](ホスト ツールチェーン相当の場合は "@rules_java//toolchains:current_host_java_runtime" )を設定する任意のルールで使用できます。

JDK のほとんどのツールは直接使用しないでください。組み込みの Java ルールでは、アップストリーム ツールで表現できるよりもはるかに高度な Java コンパイルとパッケージング のアプローチ(インターフェース Jar、ヘッダー インターフェース Jar、高度に最適化された Jar パッケージングとマージの実装など)を使用します。

これらの変数は、言語の専門家がまれに使用するフォールバック メカニズムです。 使用する場合は、まず Bazel デベロッパーにお問い合わせください。

  • JAVA: 「java」コマンド(Java 仮想 マシン)。これは避けて、可能な場合は代わりに java_binary ルール を使用してください。相対パスの場合があります。`java` を呼び出す前にディレクトリを変更する必要がある場合は、変更する前に作業ディレクトリをキャプチャする必要があります。
  • JAVABASE: Java ユーティリティを含むベース ディレクトリ。相対パスの場合があります。「bin」 サブディレクトリがあります。

Starlark で定義された変数

ルールとツールチェーンの作成者は、 完全にカスタムの変数を 定義できます。TemplateVariableInfo プロバイダを返すことで。` toolchains` 属性を介してこれらに依存するルールは、その値を読み取ることができます。

Starlark で定義された変数の例をご覧ください。