ラベル

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

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

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

正規のリポジトリ名は、@@rules_java++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 というパッケージが存在しない場合でも、常に //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 ファイル