ラベル

問題を報告 ソースを表示

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

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

ラベルの最初の部分はリポジトリ名 @@myrepo です。二重 @ 構文は、これが正規リポジトリ名であり、ワークスペース内で一意であることを意味します。正規リポジトリ名を持つラベルは、出現するコンテキストに関係なくターゲットを明確に識別します。

多くの場合、正規リポジトリ名は @@rules_java~7.1.0~toolchains~local_jdk のような難解な文字列です。よくあるのは、次のような見かけ上のリポジトリ名を持つラベルです。

@myrepo//my/app/main:app_binary

唯一の違いは、リポジトリ名の先頭に 2 つではなく 1 つの @ が付いている点です。これは、見かけ上の名前 myrepo のリポジトリを参照しています。これは、このラベルが出現するコンテキストに応じて異なる可能性があります。

通常、ラベルが使用されているリポジトリと同じリポジトリを参照する場合は、リポジトリ名の部分を省略できます。そのため、@@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 を使用してパッケージを参照することをおすすめします。これは、パッケージ名が絶対的なものであり、ワークスペースの最上位ディレクトリをルート化していることが明確に伝わるからです。

相対ラベルを使用して他のパッケージ内のターゲットを参照することはできません。この場合、リポジトリ ID とパッケージ名を必ず指定する必要があります。たとえば、ソースツリーにパッケージ 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 Query Language などのラベルを操作するツールやスクリプトを簡単に作成できるようになります。

使用できるターゲット名の正確な詳細は次のとおりです。

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

target-name は、パッケージ内のターゲットの名前です。ルールの名前は、BUILD ファイル内のルールの宣言にある name 属性の値です。ファイルの名前は、BUILD ファイルを含むディレクトリからの相対パス名です。

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

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

不適切 - 他のパッケージ内のファイルを参照するために .. を使用しない

正解 - //package-name:filename を使用します。

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

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

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

パッケージの名前は、BUILD ファイルを含むディレクトリの名前です。これは、パッケージを含むリポジトリの最上位ディレクトリへの相対名です。例: my/app

技術的なレベルでは、Bazel では次の処理が適用されます。

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

実践的レベル:

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

ルール

ルールは、入力と出力の関係、および出力を作成するステップを指定します。ルールは、さまざまな種類(ルールクラスとも呼ばれます)のいずれかになります。ルールクラスは、コンパイル済みの実行可能ファイルとライブラリ、テスト実行可能ファイル、その他のサポートされている出力を生成します(ビルド百科事典を参照)。

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

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

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

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

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

多くのルールに存在する srcs 属性のタイプは「ラベルのリスト」です。その値は、ラベルのリストです。各ラベルは、このルールの入力となるターゲットの名前になります。

ルールの種類の名前は任意ですが、ルールによって生成されたファイルの名前のほうが興味深いこともあります。これは genrules にも当てはまります。詳細については、一般ルール: genrule をご覧ください。

また、名前が重要な場合もあります。たとえば、*_binary ルールと *_test ルールの場合、ビルドによって生成された実行可能ファイルの名前はルール名によって決まります。

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

ターゲット BUILD ファイル