ラベル

問題を報告する ソースを表示 ナイトリー · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ラベルはターゲットの識別子です。一般的なラベルの完全な標準形式は次のようになります。

@@myrepo//my/app/main:app_binary

ラベルの最初の部分はリポジトリ名 @@myrepo です。2 つの @ 構文は、これが正規のリポジトリ名であり、ワークスペース内で一意であることを示します。正規リポジトリ名を持つラベルは、どのコンテキストに表示されても、ターゲットを明確に識別します。

多くの場合、正規リポジトリ名は @@rules_java++toolchains+local_jdk のような難解な文字列です。よく見かけるのは、明らかなリポジトリ名が付いたラベルです。次に例を示します。

@myrepo//my/app/main:app_binary

唯一の違いは、リポジトリ名の先頭に 2 つではなく 1 つの @ が付いていることです。これは、myrepo という表示名の repo を指します。このラベルが表示されるコンテキストによっては、異なる場合があります。

ラベルが使用元のリポジトリを参照している一般的なケースでは、リポジトリ名の部分を省略できます。したがって、@@myrepo 内では、最初のラベルは通常次のように記述されます。

//my/app/main:app_binary

ラベルの 2 番目の部分は、修飾されていないパッケージ名 my/app/main です。これは、リポジトリのルートからのパッケージのパスに相当します。リポジトリ名と修飾されていないパッケージ名を組み合わせて、完全修飾パッケージ名 @@myrepo//my/app/main を形成します。ラベルが使用されているパッケージと同じパッケージを参照する場合は、パッケージ名(必要に応じてコロン)を省略できます。したがって、@@myrepo//my/app/main 内でこのラベルは次のいずれかの方法で記述できます。

app_binary
:app_binary

ファイルの場合はコロンを省略し、ルールの場合はコロンを保持するのが慣例ですが、それ以外に意味はありません。

コロン(:)の後の部分 app_binary は、修飾されていないターゲット名です。パッケージパスの最後のコンポーネントと一致する場合は、そのコンポーネントとコロンを省略できます。したがって、次の 2 つのラベルは同等です。

//my/app/lib
//my/app/lib:lib

パッケージのサブディレクトリにあるファイル ターゲットの名前は、パッケージのルート(BUILD ファイルを含むディレクトリ)を基準としたファイルのパスです。このファイルは、リポジトリの my/app/main/testdata サブディレクトリにあります。

//my/app/main:testdata/input.txt

//my/app@@some_repo//my/app などの文字列には、使用されるコンテキストに応じて 2 つの意味があります。Bazel がラベルを想定している場合、それぞれ //my/app:app@@some_repo//my/app:app を意味します。ただし、Bazel がパッケージを想定している場合(package_group 仕様など)、そのラベルを含むパッケージを参照します。

BUILD ファイルでよく見られる間違いは、//my/app を使用してパッケージを参照すること、またはパッケージ内のすべてのターゲットを参照することです。これは正しくありません。これは //my/app:app と同等であるため、現在のリポジトリの my/app パッケージ内の app ターゲットの名前を指定します。

ただし、package_group の仕様または .bzl ファイルでは、パッケージ名が絶対であり、ワークスペースの最上位ディレクトリにルートされていることを明確に示すため、//my/app を使用してパッケージを参照することをおすすめします。

相対ラベルを使用して他のパッケージ内のターゲットを参照することはできません。この場合は、リポジトリ識別子とパッケージ名を常に指定する必要があります。たとえば、ソースツリーにパッケージ my/app とパッケージ my/app/testdata の両方(これらの 2 つのディレクトリにはそれぞれ独自の BUILD ファイル)が含まれている場合、後者のパッケージには testdepot.zip という名前のファイルが含まれています。//my/app:BUILD 内でこのファイルを参照する方法は 2 つあります(1 つは間違っていて、もう 1 つは正しい)。

誤り - testdata は別のパッケージであるため、相対パスは使用できません。

testdata/testdepot.zip

正しい - 完全なパスで testdata を参照

//my/app/testdata:testdepot.zip

@@// で始まるラベルはメイン リポジトリへの参照であり、外部リポジトリからでも機能します。したがって、外部リポジトリから参照する場合、@@//a/b/c//a/b/c とは異なります。前者はメイン リポジトリを参照しますが、後者は外部リポジトリ自体で //a/b/c を検索します。これは、メイン リポジトリ内のターゲットを参照し、外部リポジトリから使用されるルールをメイン リポジトリに記述する場合に特に重要です。

ターゲットを参照するさまざまな方法については、ターゲット パターンをご覧ください。

ラベルの語彙仕様

ラベル構文では、シェルにとって特別な意味を持つメタ文字の使用は推奨されません。これにより、誤って引用符を付ける問題を回避し、Bazel クエリ言語など、ラベルを操作するツールやスクリプトを簡単に作成できます。

許可されるターゲット名の詳細は次のとおりです。

ターゲット名 - package-name:target-name

target-name は、パッケージ内のターゲットの名前です。ルールの名前は、BUILD ファイル内のルール宣言の name 属性の値です。ファイル名は、BUILD ファイルを含むディレクトリを基準としたパス名です。

ターゲット名は、azAZ09 のセットと句読点記号 !%-@^_"#$&'()*-+,;<=>?[]{|}~/. の文字のみで構成する必要があります。

ファイル名は、通常形式の相対パス名にする必要があります。つまり、先頭または末尾にスラッシュを付けることはできません(例: /foofoo/ は禁止されています)。また、パス区切り文字として連続する複数のスラッシュを含めることもできません(例: foo//bar)。同様に、上位レベルの参照(..)と現在のディレクトリの参照(./)も禁止されています。

誤り - .. を使用して他のパッケージ内のファイルを参照しないでください。

正解 - //package-name:filename を使用

ファイル ターゲットの名前に / を使用することは一般的ですが、ルールの名前に / を使用しないでください。特にラベルの省略形を使用すると、読者が混乱する可能性があります。ラベル //foo/bar/wiz は、そのようなパッケージ foo/bar/wiz がない場合でも、常に //foo/bar/wiz:wiz の省略形です。ターゲットが存在する場合でも、//foo:bar/wiz を参照することはありません。

ただし、スラッシュを使用すると便利な場合や、必要な場合もあります。たとえば、特定のルールの名前は、パッケージのサブディレクトリにある主ソースファイルと一致する必要があります。

パッケージ名 - //package-name:target-name

パッケージの名前は、BUILD ファイルを含むディレクトリの名前です。このディレクトリは、そのリポジトリのトップレベル ディレクトリを基準としています。例: my/app

技術的なレベルでは、Bazel は次のことを適用します。

  • パッケージ名で使用できる文字は、小文字の az、大文字の AZ、数字の 09、文字の ! \"#$%&'()*+,-.;<=>?@[]^_`{|}(スペース文字も使用できます)、もちろんスラッシュ /(ディレクトリ区切り文字であるため)です。
  • パッケージ名の先頭または末尾にスラッシュ文字 / を使用できません。
  • パッケージ名にサブ文字列 // を含めることはできません。これは意味がありません。対応するディレクトリ パスはどれですか?
  • パッケージ名には、/.//..//.../ などのサブ文字列を含めることはできません。これは、パス文字列のドット文字のセマンティックな意味を考慮して、論理パッケージ名と物理ディレクトリ名の変換時に混乱を避けるために行われます。

実用的なレベルでは、

  • モジュール システムにとって重要なディレクトリ構造を持つ言語(Java など)では、その言語で有効な識別子であるディレクトリ名を選択することが重要です。たとえば、先頭に数字を付けたり、特殊文字(特にアンダースコアとハイフン)を使用しないでください。
  • Bazel はワークスペースのルート パッケージ(//:foo など)内のターゲットをサポートしていますが、意味のあるすべてのパッケージにわかりやすい名前を付けられるように、そのパッケージは空のままにしておくことをお勧めします。

ルール

ルールでは、入力と出力の関係と、出力をビルドする手順を指定します。ルールには、ビルド百科事典で説明されているように、コンパイルされた実行可能ファイルとライブラリ、テスト実行可能ファイル、その他のサポートされている出力を生成するさまざまな種類(ルールクラスと呼ばれることもある)があります。

BUILD ファイルは、ルールを呼び出してターゲットを宣言します。

次の例では、cc_binary ルールを使用してターゲット my_app を宣言しています。

cc_binary(
    name = "my_app",
    srcs = ["my_app.cc"],
    deps = [
        "//absl/base",
        "//absl/strings",
    ],
)

すべてのルール呼び出しには name 属性(有効なターゲット名である必要があります)があり、BUILD ファイルのパッケージ内のターゲットを宣言します。

すべてのルールには一連の属性があります。特定のルールに適用される属性、および各属性の重要性とセマンティクスは、ルールの種類の関数です。ルールとそれに対応する属性のリストについては、Build Encyclopedia をご覧ください。各属性には名前と型があります。属性に設定できる一般的な型には、整数、ラベル、ラベルのリスト、文字列、文字列のリスト、出力ラベル、出力ラベルのリストなどがあります。すべての属性をすべてのルールで指定する必要はありません。したがって、属性はキー(名前)からオプションの型付き値への辞書を形成します。

多くのルールに存在する srcs 属性の型は「ラベルのリスト」です。値が存在する場合、それはラベルのリストであり、それぞれがこのルールへの入力となるターゲットの名前です。

ルールの種類の名前は任意の場合があり、ルールによって生成されるファイルの名前の方が重要です。これは genrules の場合も同様です。詳細については、一般ルール: genrule をご覧ください。

他のケースでは、名前が重要です。たとえば、*_binary ルールと *_test ルールでは、ルール名によってビルドによって生成される実行可能ファイルの名前が決まります。

ターゲット上のこの有向非巡回グラフは、ターゲット グラフまたはビルド依存関係グラフと呼ばれ、Bazel クエリツールが動作するドメインです。

ターゲット BUILD ファイル