関数

目次

パッケージ

package(default_deprecation, default_testonly, default_visibility, features)

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

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

引数

属性 説明
default_visibility

List of labels; optional

このパッケージ内のルールのデフォルトの公開設定。

ルールの visibility 属性で特に指定されていない限り、このパッケージ内のすべてのルールには、この属性で指定された公開設定があります。この属性の構文の詳細については、visibility のドキュメントをご覧ください。 パッケージのデフォルトの公開設定は、デフォルトで公開されている exports_files には適用されません。

default_deprecation

String; optional

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

default_testonly

Boolean; optional; default is False except as noted

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

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

features

List strings; optional

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

この機能は主に、ビルドシステムでなんらかの特別な処理が必要なパッケージにタグを付ける際に使用します。ビルドシステムの担当者から明示的に求められない限り、この属性は使用しないでください。

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

package_group

package_group(name, packages, includes)

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

パッケージ グループは、主に公開設定に使用されます。一般公開されているターゲットは、ソースツリー内のすべてのパッケージから参照できます。非公開でアクセスできるターゲットは、それ自体のパッケージ内でのみ参照できます(サブパッケージ内では参照できません)。それらの極端な場合、ターゲットは自身のパッケージに加えて、1 つ以上のパッケージ グループによって記述されるパッケージへのアクセスも許可できます。公開設定システムの詳細については、visibility 属性をご覧ください。

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

パッケージ グループは技術的にはターゲットですが、ルールによって作成されず、可視性保護もありません。

引数

属性 説明
name

Name; required

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

packages

List of strings; optional

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

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

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

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

パッケージ グループに、正の仕様の少なくとも 1 つに一致し、負の仕様のいずれにも合致するパッケージが含まれている たとえば、値 [//foo/..., -//foo/tests/...] には、//foo/tests のサブパッケージではない //foo のすべてのサブパッケージが含まれます。(//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

List of labels; optional

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

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

反転パッケージ仕様と併用する場合は、各グループのパッケージのセットが最初に個別に計算され、その結果が結合されます。つまり、あるグループ内で反転された指定が、別のグループ内の指定に影響を与えないことを意味します。

次の 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 関数でパッケージのデフォルトの公開設定が指定されていても、すべてのパッケージがファイルを表示します。ライセンスを指定することもできます。

次の例では、test_data パッケージのテキスト ファイルである golden.txt をエクスポートして、他のパッケージ(テストの 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 ファイルに完全一致します。
  • ファイルが .txt で終わる場合、foo/*.txtfoo/ ディレクトリ内のすべてのファイルに一致します(foo/ がサブパッケージの場合を除く)。
  • foo/a*.htm* は、foo/ ディレクトリ内の a で始まり任意の文字列(空でもよい)を含み、.htm を持ち、別の任意の文字列(例: foo/axx.htmfoo/a.htmlfoo/axxx.html など)を持つすべてのファイルに一致します。
  • **/a.txt は、このパッケージのすべてのサブディレクトリ内のすべての a.txt ファイルに一致します。
  • **/bar/**/*.txt は、生成されたパス上の少なくとも 1 つのディレクトリが bar である場合、このパッケージのすべてのサブディレクトリにあるすべての .txt ファイルに一致します。xxx/bar/yyy/zzz/a.txtbar/a.txt** もゼロセグメントと一致します)、bar/zzz/a.txt など
  • ** は、このパッケージのすべてのサブディレクトリ内のすべてのファイルを照合します。
  • ** は単独でセグメントとして機能する必要があるため、foo**/a.txt は無効なパターンです。

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

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

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

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

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

    glob() はパスのリストを返すため、他のルールの属性(srcs = glob(["*.cc"]) など)で glob() を使用すると、一致したパスを明示的にリストする場合と同じ効果があることに注意してください。たとえば、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 または package-path の別の場所として)存在する場合、x/y/z.cc は含まれません。つまり、glob 式の結果は、BUILD ファイルの存在に実際に依存します。つまり、x/y というパッケージが存在しない場合、または --deleted_packages フラグを使用して削除済みとマークされた場合は、同じ glob 式に x/y/z.cc が含まれます。

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

一般的には、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",
    ],
    ...
)

Experimentsal.txt を除く、すべての txt ファイルをディレクトリ testdata に含めます。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"]),
)

このディレクトリと、そのパスに Testing という名前のディレクトリが含まれているものを除くすべてのサブディレクトリにあるすべての Java ファイルからビルドされたライブラリを作成します。ビルドの増分が減少し、ビルド時間が増加するため、このパターンはできる限り避けてください。

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 つが他の条件を専門分野化した場合は、その条件が優先されます。条件 B が A と同じフラグと制約値すべてに加えて、追加のフラグまたは制約値を持つ場合、条件 B は条件 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(include, exclude=[], allow_empty=True)

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

    返されるサブパッケージのリストは並べ替えられており、exclude 内のパターンではなく、include 内のパターンに一致する現在の読み込みパッケージからの相対パスが含まれます。

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

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

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