ラベルはターゲットの識別子です。完全な正規形式の一般的なラベルは次のようになります。
@@myrepo//my/app/main:app_binary
ラベルの最初の部分はリポジトリ名 @@myrepo
です。二重の @
構文は、これがワークスペース内で一意の正規のリポジトリ名であることを示します。正規リポジトリ名を含むラベルは、どのコンテキストで表示されてもターゲットを一意に識別します。
正規のリポジトリ名は、@@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
を使用することが推奨されます。これは、パッケージ名が絶対パスであり、ワークスペースの最上位ディレクトリをルートとしていることを明確に伝えるためです。
相対ラベルを使用して他のパッケージのターゲットを参照することはできません。この場合、リポジトリ 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
ファイルを含むディレクトリに対するパス名です。
ターゲット名は、a
~z
、A
~Z
、0
~9
の文字セットと句読記号 !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
から完全に構成されている必要があります。
ファイル名は正規形の相対パス名にする必要があります。つまり、スラッシュで始まったり終わったりしない(/foo
や foo/
は禁止)、パス区切り文字として複数のスラッシュが連続して含まれない(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 は次のことを強制します。
- パッケージ名に使用できる文字は、小文字の
a
~z
、大文字のA
~Z
、数字の0
~9
、文字! \"#$%&'()*+,-.;<=>?@[]^_`{|}
(スペース文字が含まれています)、スラッシュ/
(ディレクトリ区切り文字)です。 - パッケージ名の先頭または末尾にスラッシュ文字
/
を使用することはできません。 - パッケージ名に部分文字列
//
を含めることはできません。これは意味がありません。対応するディレクトリ パスはどうなるでしょうか? - パッケージ名に
/./
、/../
、/.../
などの部分文字列を含めることはできません。この制限は、パス文字列内のドット文字の意味を考慮して、論理パッケージ名と物理ディレクトリ名の間の変換で混乱が生じないようにするために実施されています。
実際には、次のようになります。
- モジュール システムにとってディレクトリ構造が重要な言語(Java など)では、その言語で有効な識別子となるディレクトリ名を選択することが重要です。たとえば、先頭に数字を使用したり、特殊文字(特にアンダースコアやハイフン)を使用したりしないでください。
- Bazel はワークスペースのルート パッケージ(
//:foo
など)のターゲットをサポートしていますが、すべての意味のあるパッケージにわかりやすい名前を付けるため、そのパッケージは空のままにしておくことをおすすめします。
ルール
ルールは、入力と出力の関係と、出力を構築する手順を指定します。ルールにはさまざまな種類(ルールクラスと呼ばれることもあります)があり、ビルド百科事典で説明されているように、コンパイル済みの実行可能ファイルとライブラリ、テスト実行可能ファイル、その他のサポートされている出力を生成します。
BUILD
ファイルは、ルールを呼び出すことでターゲットを宣言します。
次の例では、cc_binary
ルールを使用してターゲット my_app
の宣言を確認できます。
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
すべてのルール呼び出しには、BUILD
ファイルのパッケージ内のターゲットを宣言する name
属性(有効なターゲット名である必要があります)があります。
すべてのルールには一連の属性があります。特定のルールに適用可能な属性、各属性の重要性とセマンティクスは、ルールの種類によって異なります。ルールとその対応する属性の一覧については、ビルド百科事典をご覧ください。各属性には名前と型があります。属性が持つことができる一般的な型には、整数、ラベル、ラベルのリスト、文字列、文字列のリスト、出力ラベル、出力ラベルのリストなどがあります。すべての属性をすべてのルールで指定する必要はありません。属性は、キー(名前)からオプションの型付き値への辞書を形成します。
多くのルールに存在する srcs
属性の型は「ラベルのリスト」です。値が存在する場合、その値はラベルのリストであり、各ラベルはこのルールの入力であるターゲットの名前です。
場合によっては、ルール種類の名前はやや任意であり、ルールによって生成されるファイルの名前の方が重要です。これは genrules にも当てはまります。詳細については、一般的なルール: genrule をご覧ください。
場合によっては、名前が重要になることがあります。たとえば、*_binary
ルールと *_test
ルールの場合、ルール名によってビルドで生成される実行可能ファイルの名前が決まります。
ターゲットの有向非巡回グラフは、ターゲット グラフまたはビルド依存関係グラフと呼ばれ、Bazel Query ツールが動作するドメインです。
ターゲット | BUILD ファイル |