関数

目次

package

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

この関数は、パッケージ内のすべてのルールに適用されるメタデータを宣言します。パッケージ(BUILD ファイル)内で使用されるのは 1 回のみです。

リポジトリ全体 のすべてのルールに適用されるメタデータを宣言する対応する関数については、リポジトリのルートにあるrepo()関数を REPO.bazelファイルで使用します。repo() 関数は、package() とまったく同じ引数を取ります。

package() 関数は、ファイルの先頭にあるすべての load() ステートメントの直後、ルールの前に呼び出す必要があります。

引数

属性 説明
default_applicable_licenses

default_package_metadata. のエイリアス。

default_visibility

ラベルのリスト。デフォルトは[]

このパッケージ内の最上位ルール ターゲットとシンボリック マクロのデフォルトの公開設定。つまり、シンボリック マクロ内で宣言されていないターゲットとシンボリック マクロです。ターゲットまたはマクロで visibility 値が指定されている場合、この属性 は無視されます。

この属性の構文の詳細については、 visibility のドキュメントをご覧ください。パッケージのデフォルトの公開設定は、 exports_files には適用されません。

default_deprecation

文字列。デフォルトは ""

このパッケージ内のすべてのルールのデフォルトの deprecation メッセージを設定します。

default_package_metadata

ラベルのリスト。デフォルトは[]

パッケージ内の他のすべてのターゲットに適用されるメタデータ ターゲットのデフォルト リストを設定します。 通常、これらは OSS パッケージとライセンス宣言に関連するターゲットです。 例については、rules_license をご覧ください。

default_testonly

ブール値。デフォルトは False(注記がある場合を除く)

このパッケージ内のすべてのルールのデフォルトの testonly プロパティを設定します。

javatests のパッケージでは、デフォルト値は True です。

features

文字列のリスト。デフォルトは []

この BUILD ファイルのセマンティクスに影響するさまざまなフラグを設定します。

この機能は主に、ビルドシステムで作業しているユーザーが、特別な処理が必要なパッケージにタグを付けるために使用します。ビルドシステムで作業しているユーザーから 明示的にリクエストされない限り、この機能は使用しないでください。

次の宣言では、このパッケージのルールはパッケージ グループ //foo:target のメンバーにのみ表示されることを宣言しています。ルールに個別の公開設定の宣言がある場合は、この指定がオーバーライドされます。
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

この関数は、パッケージ のセットを定義し、そのセットにラベルを関連付けます。ラベルは visibility 属性で参照できます。

パッケージ グループは主に公開設定の制御に使用されます。公開されているターゲットは、ソースツリー内のすべてのパッケージから参照できます。非公開のターゲットは、独自のパッケージ内でのみ参照できます(サブパッケージは不可)。 これらの極端なケースの中間として、ターゲットは、独自のパッケージと、1 つ以上のパッケージ グループで記述されたパッケージへのアクセスを許可できます。公開設定システムの詳細については、 visibility 属性をご覧ください。

特定のパッケージがグループに含まれると見なされるのは、そのパッケージが packages 属性と一致する場合、または includes 属性で指定された他のパッケージ グループのいずれかにすでに含まれている場合です。

パッケージ グループは技術的にはターゲットですが、ルールによって作成されるものではなく、公開設定の保護もありません。

引数

属性 説明
name

名前。必須

このターゲットの一意の名前。

packages

文字列のリスト。デフォルトは []

ゼロ個以上のパッケージ仕様のリスト。

各パッケージ仕様文字列は、次のいずれかの 形式になります。

  1. パッケージのリポジトリを含まない完全な名前。先頭は 二重スラッシュ。たとえば、//foo/bar は、その名前を持ち、パッケージ グループと同じリポジトリに存在するパッケージ を指定します。
  2. 上記と同じですが、末尾に /... が付いています。たとえば、 //foo/... は、//foo とそのすべての サブパッケージのセットを指定します。//... は、現在のリポジトリ内のすべてのパッケージを指定します。
  3. 文字列 public または private。それぞれすべてのパッケージまたはパッケージなしを指定します。(この形式では、フラグ --incompatible_package_group_has_public_syntax を設定する必要があります)。

また、最初の 2 種類のパッケージ仕様には、否定を示す接頭辞 - を付けることもできます。

パッケージ グループには、正の仕様の少なくとも 1 つに一致し、負の仕様のいずれにも一致しないパッケージが含まれます。たとえば、値 [//foo/..., -//foo/tests/...] には、//foo のサブパッケージではない //foo/tests のすべてのサブパッケージが含まれます。(//foo 自体は 含まれますが、//foo/tests 自体は含まれません)。

公開設定を除き、現在のリポジトリ外のパッケージを直接指定する方法はありません。

この属性がない場合は、空のリストに設定した場合と同じです。これは、private のみを含むリストに設定した場合と同じです。

注: Bazel 6.0 より前のバージョンでは、仕様 //...public と同じという以前の動作がありました。この 動作は、 --incompatible_fix_package_group_reporoot_syntaxが 有効になっている場合に修正されます。これは、Bazel 6.0 以降のデフォルトです。

注: Bazel 6.0 より前のバージョンでは、この属性が bazel query --output=proto(または --output=xml)の一部としてシリアル化されると、先頭のスラッシュが省略されます。たとえば、//pkg/foo/...\"pkg/foo/...\" として出力されます。この動作は、 --incompatible_package_group_includes_double_slash が 有効になっている場合に修正されます。これは、Bazel 6.0 以降のデフォルトです。

includes

ラベルのリスト。デフォルトは[]

このパッケージに含まれる他のパッケージ グループ。

この属性のラベルは、他のパッケージ グループを参照する必要があります。 参照されるパッケージ グループ内のパッケージは、この パッケージ グループの一部と見なされます。これは推移的です。パッケージ グループ a にパッケージ グループ b が含まれ、b にパッケージ グループ c が含まれている場合、 c 内のすべてのパッケージも a のメンバーになります。

否定されたパッケージ仕様とともに使用する場合、各グループのパッケージのセットは最初に個別に計算され、その結果が結合されます。つまり、1 つのグループの否定された 仕様は、別のグループの仕様には影響しません。

次の package_group 宣言では、熱帯の果物を含む「tropical」というパッケージ グループを指定しています。

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

次の宣言では、架空のアプリケーションのパッケージ グループを指定しています。

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files() は、他のパッケージにエクスポートされるこのパッケージに属するファイルのリストを指定します。

パッケージの BUILD ファイルは、別のパッケージに属するソースファイルを、 exports_files() ステートメントで明示的にエクスポートされている場合にのみ、直接参照できます。詳しくは、 ファイルの公開設定をご覧ください。

レガシー動作として、フラグ --incompatible_no_implicit_file_export が切り替えられるまで、ルールへの入力として指定されたファイルもデフォルトの公開設定でエクスポートされます。ただし、この動作に依存することは避けて、積極的に 移行する必要があります。

引数

引数は、現在のパッケージ内のファイル名のリストです。公開設定の宣言を指定することもできます。この場合、ファイルは指定されたターゲットに表示されます。公開設定が指定されていない場合、ファイル は、`package` 関数でパッケージのデフォルトの公開設定が 指定されていても、すべてのパッケージに表示されます。packageライセンス を指定することもできます。

次の例では、golden.txt をエクスポートします。これは、test_data パッケージのテキスト ファイルであり、他のパッケージで使用できるようにします(たとえば、テストの data 属性で使用します)。

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob は、特定のパスパターンに一致するすべてのファイルを検索し、そのパスの新しい変更可能な並べ替えられたリストを返すヘルパー関数です。Glob は、独自のパッケージ内のファイルのみを検索し、ソースファイルのみを検索します(生成されたファイルや他のターゲットは検索しません)。

ファイルのパッケージ相対パスが include パターンのいずれかに一致し、exclude パターンのいずれにも一致しない場合、ソースファイルのラベルが結果に含まれます。

include リストと exclude リストには、現在のパッケージに対する相対パスパターンが含まれています。すべてのパターンは、1 つ以上のパスセグメントで構成されます。通常、Unix パスと同様に、これらのセグメントは / で区切られます。パターン内のセグメントは、パスのセグメントと照合されます。セグメントには * ワイルドカードを含めることができます。これは ディレクトリ区切り文字 / を除く、パスセグメント内の任意のサブ文字列(空のサブ文字列を含む)と一致します。このワイルドカードは、1 つのパスセグメント内で複数回使用できます。また、** ワイルドカードは 0 個以上の完全なパスセグメントと一致しますが、スタンドアロンのパスセグメントとして宣言する必要があります。

例:
  • foo/bar.txt は、このパッケージ内の foo/bar.txt ファイルと完全に一致します(foo/ がサブパッケージでない場合)。
  • foo/*.txt は、ファイルが .txt で終わる場合、foo/ ディレクトリ内のすべてのファイルと一致します(foo/ がサブパッケージでない場合)。
  • foo/a*.htm* は、foo/ ディレクトリ内のすべてのファイルと一致します。このファイルは、a で始まり、任意の文字列(空の場合もあります)、.htm が続き、別の任意の文字列で終わります(foo/ がサブパッケージでない場合)。たとえば、foo/axx.htmfoo/a.htmlfoo/axxx.html などです。
  • foo/* は、foo/ ディレクトリ内のすべてのファイルと一致します(foo/ がサブパッケージでない場合)。foo ディレクトリ自体とは一致しません。exclude_directories が 0 に設定されていても
  • foo/** は、パッケージの最初のレベルのサブディレクトリ foo/ の下にあるサブパッケージ以外のすべてのサブディレクトリ内のすべてのファイルと一致します。exclude_directories が 0 に設定されている場合、foo ディレクトリ自体もパターンと一致します。この場合、** は 0 個のパスセグメントと一致すると見なされます。
  • **/a.txt は、このパッケージの ディレクトリとサブパッケージ以外のサブディレクトリにある a.txt ファイルと一致します。
  • **/bar/**/*.txt は、このパッケージのサブパッケージ以外のすべてのサブディレクトリ内のすべての .txt ファイルと一致します。結果のパスに bar という名前のディレクトリが少なくとも 1 つある場合(xxx/bar/yyy/zzz/a.txtbar/a.txt など)。** は 0 個のセグメントとも一致します。bar/zzz/a.txt
  • ** は、このパッケージのサブパッケージ以外のすべてのサブディレクトリ内のすべてのファイルと一致します。
  • foo**/a.txt は無効なパターンです。** はセグメントとして単独で存在する必要があります。
  • foo/ は無効なパターンです。 / の後に定義された 2 番目のセグメントが空の文字列であるためです。

exclude_directories 引数が有効(1 に設定)の場合、ディレクトリ タイプのファイルは結果から除外されます(デフォルトは 1)。

allow_empty 引数が False に設定されている場合、結果が空のリストになる場合は glob 関数でエラーが発生します。

重要な制限事項と注意事項がいくつかあります。

  1. glob() は BUILD ファイルの評価中に実行されるため、 glob() はソースツリー内のファイルのみと一致し、生成されたファイルとは一致しません。ソースファイルと生成されたファイルの両方を必要とするターゲットをビルドする場合は、生成されたファイルの明示的なリストを glob に追加する必要があります。下記の :mylib および :gen_java_srcs の例をご覧ください。

  2. ルールが一致するソースファイルと同じ名前の場合、ルールは "シャドウ" ファイルをします。

    これを理解するには、glob() はパスのリストを返すため、他のルールの属性で glob() を使用する(例: srcs = glob(["*.cc"]))ことは、一致するパスを明示的にリストする場合と同じ効果があることを覚えておいてください。たとえば、glob()["Foo.java", "bar/Baz.java"] を生成し、パッケージに「Foo.java」というルールもある場合(Bazel は警告しますが、許可されています)、 glob() のコンシューマーは「Foo.java」ファイルではなく「Foo.java」ルール(その出力)を使用します。詳細については、GitHub の問題 #10395 をご覧ください。

  3. glob はサブディレクトリ内のファイルと一致する場合があります。 また、サブディレクトリ名に ワイルドカードを使用することもできます。ただし...
  4. ラベルはパッケージ境界を越えることはできません。glob はサブパッケージ内のファイルと一致しません。

    たとえば、パッケージ x の glob 式 **/*.cc には、 x/y がパッケージとして存在する場合( x/y/BUILD として、またはパッケージパスの別の場所)、x/y/z.cc は含まれません。つまり、glob 式の結果は実際には BUILD ファイルの存在に依存します。つまり、x/y/z.cc というパッケージが存在しない場合、または --deleted_packages フラグを使用して削除済みとしてマークされている場合、同じ glob 式に x/y が含まれます。

  5. 上記の制限は、使用するワイルドカードに関係なく、すべての glob 式に適用されます。
  6. ファイル名が . で始まる非表示ファイルは、 ** ワイルドカードと * ワイルドカードの両方で完全に一致します。複合パターンで隠しファイル と一致させる場合は、パターンを.で始める必要があります。たとえば、 *.*.txt.foo.txt と一致しますが、*.txt は一致しません。 非表示ディレクトリも同様に一致します。非表示ディレクトリ には、入力として必要ないファイルが含まれている可能性があり、 不要な glob ファイルの数とメモリ使用量が増加する可能性があります。非表示ディレクトリを除外するには、 [exclude] リスト引数に追加します。
  7. 「**」ワイルドカードには 1 つのコーナーケースがあります。パターン "**" はパッケージのディレクトリ パスと一致しません。つまり、glob(["**"], exclude_directories = False) は、現在のパッケージのディレクトリの直下にあるすべてのファイルとディレクトリに推移的に一致します(サブパッケージのディレクトリには入りません。これについては前の注をご覧ください)。

一般に、glob パターンには、裸の '*' を使用するのではなく、適切な拡張子(*.html など)を指定 してください。名前を明示的に指定すると、自己文書化され、バックアップ ファイルや emacs/vi/... の自動保存ファイルと誤って一致しないようにできます。

ビルドルールを作成するときに、glob の要素を列挙できます。これにより、入力ごとに個別のルールを生成できます。詳しくは、下記の 展開された glob の例をご覧ください。

glob の例

このディレクトリ内のすべての Java ファイルと、:gen_java_srcs ルールによって生成されたすべてのファイルからビルドされた Java ライブラリを作成します。

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

ディレクトリ testdata 内のすべての txt ファイル(experimental.txt を除く)を含めます。 testdata のサブディレクトリ内のファイルは含まれません。これらのファイルを含める場合は、再帰 glob(**)を使用します。

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

再帰 glob の例

テストが testdata ディレクトリとそのサブディレクトリ(およびそのサブディレクトリなど)内のすべての txt ファイルに依存するようにします。 BUILD ファイルを含むサブディレクトリは無視されます。(上記の制限事項 と注意事項をご覧ください)。

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

このディレクトリとすべてのサブディレクトリ内のすべての Java ファイルからビルドされたライブラリを作成します。ただし、パスに testing という名前のディレクトリが含まれているサブディレクトリは除きます。 このパターンは、ビルドの増分性を低下させ、ビルド時間を長くする可能性があるため、可能な限り避ける必要があります。

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

展開された glob の例

現在のディレクトリに、ファイル内の行数をカウントする *_test.cc の個別の genrule を作成します。

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

上記の BUILD ファイルがパッケージ //foo にあり、パッケージに一致するファイルが 3 つ(a_test.cc、b_test.cc、c_test.cc)含まれている場合、bazel query '//foo:all' を実行すると、生成されたすべてのルールが一覧表示されます。

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

select

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() は、ルールの属性を 構成可能にするヘルパー関数です。 ほとんど の属性割り当ての右辺を置き換えることができるため、その値はコマンドラインの Bazel フラグに依存します。たとえば、これを使用して、プラットフォーム固有の依存関係を定義したり、 ルールが「デベロッパー」 モードと「リリース」モードのどちらでビルドされるかに応じて異なるリソースを埋め込んだりできます。

基本的な使用方法は次のとおりです。

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

これにより、通常のラベル リスト割り当てを、構成条件を一致する値にマッピングする select 呼び出しに置き換えることで、sh_binarysrcs 属性を構成可能にします。各条件は、 config_setting または constraint_value へのラベル 参照です。ターゲットの構成が想定される値のセットと一致する場合、「一致」します。この場合、mytarget#srcs の値は、現在の呼び出しに一致するラベルリストになります。

注:

  • 1 回の呼び出しで選択される条件は 1 つだけです。
  • 複数の条件が一致し、1 つが他の条件の特殊化である場合、 特殊化が優先されます。条件 B は、B に A と同じフラグと制約値に加えて、追加のフラグまたは制約値がある場合、条件 A の特殊化と見なされます。これは、特殊化の解決が、下記の例 2 で示すように順序を作成するように設計されていないことも意味します。
  • 複数の条件が一致し、1 つが他のすべての条件の特殊化でない場合、すべての条件が同じ値に解決されない限り、Bazel はエラーで失敗します。
  • 他の条件が一致しない場合、特別な疑似ラベル //conditions:default が 一致すると見なされます。この条件 が除外されている場合は、エラーを回避するために他のルールと一致する必要があります。
  • select は、より大きな 属性割り当ての内部に埋め込むことができます。したがって、srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) は有効な式です。
  • select は、ほとんどの属性で機能しますが、すべての属性で機能するわけではありません。互換性のない 属性は、ドキュメントでnonconfigurableとマークされています。

    subpackages

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() は、glob() と同様のヘルパー関数で、ファイルやディレクトリではなくサブパッケージを一覧表示します。 と同じパスパターンを使用し、現在読み込まれている BUILD ファイルの直接の子であるサブパッケージと一致させることができます。glob()include パターンと exclude パターンの詳細な説明と例については、glob をご覧ください。

    返されるサブパッケージのリストは並べ替えられており、現在読み込まれているパッケージに対する相対パスが含まれています。これらは、include で指定されたパターンに一致し、exclude で指定されたパターンに一致しません。

    次の例では、パッケージ foo/BUILD のすべての直接サブパッケージを一覧表示します。

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/bar/but/bad/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs1 = subpackages(include = ["**"])
    
    # results in subs1 == ["sub", "bar/baz", "bar/but/bad"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    
    subs2 = subpackages(include = ["bar/*"])
    # results in subs2 = ["bar/baz"]
    #
    # Since 'bar' is not a subpackage itself, this looks for any subpackages under
    # all first level subdirectories of 'bar'.
    
    subs3 = subpackages(include = ["bar/**"])
    # results in subs3 = ["bar/baz", "bar/but/bad"]
    #
    # Since bar is not a subpackage itself, this looks for any subpackages which are
    # (1) under all subdirectories of 'bar' which can be at any level, (2) not a
    # subpackage of another subpackages.
    
    subs4 = subpackages(include = ["sub"])
    subs5 = subpackages(include = ["sub/*"])
    subs6 = subpackages(include = ["sub/**"])
    # results in subs4 and subs6 being ["sub"]
    # results in subs5 = [].
    #
    # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a
    # subpackage of 'foo').
    # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since
    # 'foo/sub' is already a subpackage itself, the subdirectories will not be
    # traversed anymore.
    # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it
    # is returned. But the subdirectories of 'foo/sub' will not be traversed
    # anymore.
    

    一般に、この関数を直接呼び出すのではなく skylib の 'subpackages' モジュールを使用することをおすすめします。