ラベルはターゲットの識別子です。一般的なラベルの完全な正規形式は次のようになります。
@@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
を使用することをおすすめします。
相対ラベルを使用して他のパッケージ内のターゲットを参照することはできません。この場合は、リポジトリ識別子とパッケージ名を常に指定する必要があります。たとえば、ソースツリーにパッケージ 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
ファイルを含むディレクトリを基準としたパス名です。
ターゲット名は、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
属性(有効なターゲット名である必要があります)があります。
すべてのルールには一連の属性があります。特定のルールに適用される属性、および各属性の重要性とセマンティクスは、ルールの種類の関数です。ルールとそれに対応する属性のリストについては、Build Encyclopedia をご覧ください。各属性には名前と型があります。属性に設定できる一般的な型には、整数、ラベル、ラベルのリスト、文字列、文字列のリスト、出力ラベル、出力ラベルのリストなどがあります。すべての属性をすべてのルールで指定する必要はありません。したがって、属性はキー(名前)からオプションの型付き値への辞書を形成します。
多くのルールに存在する srcs
属性の型は「ラベルのリスト」です。値が存在する場合、それはラベルのリストであり、それぞれがこのルールへの入力となるターゲットの名前です。
ルールの種類の名前は任意の場合があり、ルールによって生成されるファイルの名前の方が重要です。これは genrules の場合も同様です。詳細については、一般ルール: genrule をご覧ください。
他のケースでは、名前が重要です。たとえば、*_binary
ルールと *_test
ルールの場合、ルール名によって、ビルドによって生成された実行可能ファイルの名前が決まります。
ターゲット上のこの有向非巡回グラフは、ターゲット グラフまたはビルド依存関係グラフと呼ばれ、Bazel クエリツールが動作するドメインです。
ターゲット | BUILD ファイル |