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