&make ; 変数

問題を報告 ソースを表示

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

たとえば、ユーザーが構築したビルド アクションに特定のツールチェーン パスを挿入できます。

Bazel は、すべてのターゲットで使用可能な事前定義変数と、それに依存するターゲットでのみ利用可能なカスタム変数の両方を提供します。

「Make」という用語は、これらの変数の構文とセマンティクスが、もともと GNU Make と一致することを意図して作られたという歴史上の理由です。

用途

「Make 'variable 置換」の対象としてマークされた属性は、次のように「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: fastbuilddbg、または opt。(詳細)。

パス変数

  • BINDIR: ターゲット アーキテクチャ用に生成されたバイナリツリーのベース。

    クロスコンパイルをサポートするために、ホスト アーキテクチャ上でのビルド時に実行されるプログラムには別のツリーが使用される可能性があります。

    genrule 内からツールを実行する場合、そのパスを取得するための推奨の方法は $(execpath toolname) です。この場合、toolnamegenruletools にリストされる必要があります。

  • GENDIR: ターゲット アーキテクチャ用に生成されるコードツリーのベース。

マシン アーキテクチャ変数

  • TARGET_CPU: ターゲット アーキテクチャの CPU(例: k8)。

事前定義された genrule 変数

以下に、genrulecmd 属性で特別に使用できるものを示します。この属性を機能させるためには、一般的に重要です。

事前定義された genrule 変数の例をご覧ください

  • OUTS: genruleouts リスト。出力ファイルが 1 つしかない場合は、$@ も使用できます。
  • SRCS: genrulesrcs リスト(より正確には、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 でも書き込み可能です)を試みる必要があります。

    入力を含むディレクトリへの書き込みは特に避けてください。読み取り専用のファイル システム上にある場合もあります。そうしないと、ソースツリーがゴミ箱に移動します。

事前定義のソース/出力パス変数

事前定義された変数 execpathexecpathsrootpathrootpathslocationlocations は、ラベル パラメータ($(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_outputtools 属性に含まれているため、ツールです。出力ファイル appbazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app に書き込まれます。そのため、exec パスは bazel-out/cpu-opt-exec-hash/bin/testapp/app になります。この追加の接頭辞を使用すると、結果を互いに重複させることなく、同じビルド内の 2 つの異なる CPU に対して同じターゲットをビルドできます。

    この変数に渡すラベルは 1 つのファイルのみにする必要があります。ソースファイルを表すラベルの場合、これは自動的に true になります。ルールを表すラベルの場合、ルールは 1 つの出力を生成する必要があります。これが false の場合、またはラベルの形式が正しくない場合、ビルドはエラーで失敗します。

  • rootpath: ビルドされたバイナリが、実行時にメイン リポジトリに対応するランファイル ディレクトリのサブディレクトリを基準とする依存関係を見つける際に使用できるパスを示します。注: これは、--enable_runfiles が有効になっている場合にのみ機能します。Windows では、デフォルトでは無効です。クロス プラットフォーム サポートには、代わりに rlocationpath を使用してください。

    これは execpath に似ていますが、前述の構成接頭辞が削除されます。上記の例では、empty.sourceapp はどちらも純粋なワークスペース相対パス(testapp/empty.sourcetestapp/app)を使用します。

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

    「1 つの出力のみ」の要件は execpath と同じです。

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

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

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

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

    「1 つの出力のみ」の要件は execpath と同じです。

  • location: 展開された属性に応じて execpath または rootpath の類義語。これは以前の Starlark 以前の動作であり、特定のルールに対する動作を本当に把握していない限りおすすめしません。詳細については #2475 をご覧ください。

execpathsrootpathsrlocationpathslocations は、それぞれ execpathrootpathrlocationpathslocation の複数形です。複数の出力を生成するラベルがサポートされています。出力ごとにスペースで区切られています。ゼロ出力ルールと正しくない形式のラベルによってビルドエラーが発生します。

参照されるすべてのラベルは、消費元のターゲット、srcs、出力ファイル、または deps に含まれている必要があります。それ以外の場合、ビルドは失敗します。C++ ターゲットでは、data のラベルも参照できます。

ラベルは正規の形式である必要はありません。foo:foo//somepkg:foo はすべて問題ありません。

カスタム変数

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

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

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

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

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

これらの変数は、まれに言語のエキスパートが使用するフォールバック メカニズムとなります。使用したくない場合は、最初に Bazel のデベロッパーにお問い合わせください

  • ABI: C++ ABI のバージョン。
  • AR: crosstool の「ar」コマンド。
  • C_COMPILER: C/C++ コンパイラ ID(例: llvm)。
  • CC: C および C++ コンパイラ コマンド。

    常に CC と組み合わせて CC_FLAGS を使用することを強くおすすめします。この操作はご自身の責任のもとで行ってください。

  • CC_FLAGS: genrule で使用できる C/C++ コンパイラの最小限のフラグセット。特に、CC が複数のアーキテクチャをサポートしている場合に正しいアーキテクチャを選択するためのフラグが含まれています。
  • NM: crosstool の「nm」コマンド。
  • OBJCOPY: C / C++ コンパイラと同じスイートからの objcopy コマンド。
  • STRIP: C / C++ コンパイラと同じスイートの削除コマンド。

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 属性を介してこれらの属性に依存するルールは、値を読み取れます。

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