ラベル

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

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

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

正規のリポジトリ名は、@@rules_java++toolchains+local_jdk のような難解な文字列であることがよくあります。より一般的なのは、 次のようなリポジトリ名を持つラベルです

@myrepo//my/app/main:app_binary

唯一の違いは、リポジトリ名の先頭に @ が 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 というパッケージが存在しない場合でも、常に //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 ファイルのパッケージ内でターゲットを宣言します。

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

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

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

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

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

ターゲット BUILD ファイル