目次
パッケージ
package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)
この関数は、パッケージ内のすべてのルールに適用されるメタデータを宣言します。パッケージ(BUILD ファイル)内で最大 1 回使用されます。
リポジトリ全体のすべてのルールに適用されるメタデータを宣言する対応する関数については、リポジトリのルートにある REPO.bazel ファイルの repo() 関数を使用します。repo() 関数は、package() とまったく同じ引数を取ります。
package() 関数は、ファイルの先頭にあるすべての load() ステートメントの直後、ルールの前に呼び出す必要があります。
引数
| 属性 | 説明 |
|---|---|
default_applicable_licenses |
|
default_visibility |
ラベルのリスト。デフォルトは このパッケージ内の最上位ルール ターゲットとシンボリック マクロのデフォルトの公開設定。つまり、シンボリック マクロ内で宣言されていないターゲットとシンボリック マクロです。ターゲットまたはマクロで この属性の構文の詳細については、visibility のドキュメントをご覧ください。パッケージのデフォルトの公開設定は、デフォルトで公開されている exports_files には適用されません。 |
default_deprecation |
文字列。デフォルトは このパッケージのすべてのルールにデフォルトの |
default_package_metadata |
ラベルのリスト。デフォルトは パッケージ内の他のすべてのターゲットに適用されるメタデータ ターゲットのデフォルト リストを設定します。 これらは通常、OSS パッケージとライセンス宣言に関連するターゲットです。 例については、rules_license をご覧ください。 |
default_testonly |
ブール値。特に記載のない限り、デフォルトは このパッケージ内のすべてのルールのデフォルトの
|
features |
文字列のリスト。デフォルトは この BUILD ファイルのセマンティクスに影響するさまざまなフラグを設定します。 この機能は主に、ビルドシステムに携わるユーザーが、特別な処理が必要なパッケージにタグを付けるために使用します。ビルドシステムを操作するユーザーから明示的にリクエストされない限り、このオプションは使用しないでください。 |
例
以下の宣言は、このパッケージのルールがパッケージ グループ//foo:target のメンバーにのみ表示されることを宣言しています。ルールに個別の公開設定宣言がある場合は、この仕様をオーバーライドします。
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
この関数は、パッケージのセットを定義し、ラベルをセットに関連付けます。このラベルは visibility 属性で参照できます。
パッケージ グループは主に公開設定の制御に使用されます。一般公開されているターゲットは、ソースツリー内のすべてのパッケージから参照できます。非公開のターゲットは、独自のパッケージ(サブパッケージではない)内でのみ参照できます。これらの極端な例の間で、ターゲットは独自のパッケージと、1 つ以上のパッケージ グループによって記述されたパッケージへのアクセスを許可できます。公開設定システムの詳細については、visibility 属性をご覧ください。
特定のパッケージが packages 属性と一致するか、includes 属性で指定された他のパッケージ グループのいずれかにすでに含まれている場合、そのパッケージはグループ内にあると見なされます。
パッケージ グループは技術的にはターゲットですが、ルールによって作成されるものではなく、それ自体に公開設定の保護はありません。
引数
| 属性 | 説明 |
|---|---|
name |
名前。必須 このターゲットの一意の名前。 |
packages |
文字列のリスト。デフォルトは 0 個以上のパッケージ仕様のリスト。 各パッケージ仕様文字列は、次のいずれかの形式にできます。
また、最初の 2 種類のパッケージ仕様には、否定を示す パッケージ グループには、少なくとも 1 つの正の仕様に一致し、負の仕様に一致しないパッケージが含まれます。たとえば、値 公開設定以外に、現在のリポジトリ外のパッケージを直接指定する方法はありません。 この属性がない場合は、空のリストに設定するのと同じです。これは、 注: Bazel 6.0 より前では、仕様 注: Bazel 6.0 より前では、この属性が |
includes |
ラベルのリスト。デフォルトは このパッケージ グループに含まれる他のパッケージ グループ。 この属性のラベルは、他のパッケージ グループを参照する必要があります。
参照されるパッケージ グループ内のパッケージは、このパッケージ グループの一部とみなされます。これは推移的です。パッケージ グループ 否定されたパッケージ仕様と組み合わせて使用する場合、各グループのパッケージのセットが最初に個別に計算され、その結果が結合されます。つまり、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 関数でパッケージのデフォルトの公開設定が指定されていても、ファイルはすべてのパッケージに公開されます。ライセンスを指定することもできます。
例
次の例では、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ファイルと完全に一致します(foo/がサブパッケージでない場合)。foo/*.txtは、ファイルが.txtで終わる場合、foo/ディレクトリ内のすべてのファイルと一致します(foo/がサブパッケージでない場合)。foo/a*.htm*は、foo/ディレクトリ内のすべてのファイルと一致します。このファイルはaで始まり、任意の文字列(空の場合もあります)が続き、.htmが続き、別の任意の文字列で終わります(foo/がサブパッケージの場合を除く)。たとえば、foo/axx.htm、foo/a.html、foo/axxx.htmlなどです。foo/*は、foo/ディレクトリ内のすべてのファイルに一致します(foo/がサブパッケージの場合を除く)。exclude_directoriesが 0 に設定されている場合でも、fooディレクトリ自体には一致しません。foo/**は、パッケージの第 1 レベルのサブディレクトリfoo/の下にある、サブパッケージ以外のすべてのサブディレクトリ内のすべてのファイルに一致します。exclude_directoriesが 0 に設定されている場合、fooディレクトリ自体もパターンに一致します。この場合、**はゼロのパスセグメントに一致すると見なされます。**/a.txtは、このパッケージのディレクトリとサブパッケージ以外のサブディレクトリにあるa.txtファイルと一致します。**/bar/**/*.txtは、このパッケージのサブパッケージ以外のすべてのサブディレクトリにあるすべての.txtファイルに一致します。ただし、結果のパスにbarという名前のディレクトリが少なくとも 1 つある場合(xxx/bar/yyy/zzz/a.txtやbar/a.txtなど。**はゼロセグメントにも一致することに注意してください)や、bar/zzz/a.txtの場合です。**は、このパッケージのサブパッケージ以外のすべてのサブディレクトリ内のすべてのファイルと一致します。foo**/a.txtは無効なパターンです。**はセグメントとして独立している必要があります。foo/は無効なパターンです。/の後に定義された 2 番目のセグメントが空の文字列であるためです。
exclude_directories 引数が有効(1 に設定)になっている場合、ディレクトリ タイプのファイルは結果から除外されます(デフォルトは 1)。
allow_empty 引数が False に設定されている場合、結果が空のリストになると、glob 関数はエラーになります。
重要な制限事項と注意事項がいくつかあります。
-
glob()は BUILD ファイルの評価中に実行されるため、glob()はソースツリー内のファイルのみを照合し、生成されたファイルは照合しません。ソースファイルと生成されたファイルの両方を必要とするターゲットをビルドする場合は、生成されたファイルの明示的なリストを glob に追加する必要があります。:mylibと:gen_java_srcsを使用した例を以下に示します。 -
ルールが一致したソースファイルと同じ名前の場合、ルールはファイルを「シャドー」します。
これを理解するには、
glob()がパスのリストを返すことを思い出してください。したがって、他のルールの属性(srcs = glob(["*.cc"])など)でglob()を使用すると、一致したパスを明示的にリストするのと同じ効果があります。たとえば、glob()が["Foo.java", "bar/Baz.java"]を生成するが、パッケージに「Foo.java」というルールもある場合(Bazel は警告しますが、許可されています)、glob()のコンシューマは「Foo.java」ファイルの代わりに「Foo.java」ルール(その出力)を使用します。詳細については、GitHub の問題 #10395 をご覧ください。 - glob はサブディレクトリ内のファイルと一致する場合があります。サブディレクトリ名にはワイルドカードを使用できます。しかし...
-
ラベルはパッケージ境界を越えることはできず、glob はサブパッケージ内のファイルと一致しません。
たとえば、パッケージ
xの glob 式**/*.ccには、x/yがパッケージとして(x/y/BUILDとして、またはパッケージパスの別の場所に)存在する場合、x/y/z.ccは含まれません。つまり、glob 式の結果は、実際には BUILD ファイルの存在に依存します。つまり、x/yというパッケージが存在しない場合、または --deleted_packages フラグを使用して削除済みとしてマークされている場合、同じ glob 式にx/y/z.ccが含まれます。 - 上記の制限は、使用するワイルドカードに関係なく、すべての glob 式に適用されます。
-
ファイル名が
.で始まる隠しファイルは、**と*の両方のワイルドカードに完全に一致します。隠しファイルを複合パターンと一致させるには、パターンを.で始める必要があります。たとえば、*と.*.txtは.foo.txtと一致しますが、*.txtは一致しません。非表示のディレクトリも同様に照合されます。非表示のディレクトリには、入力として不要なファイルが含まれている可能性があり、不必要にグロブされたファイルの数とメモリ消費量が増加する可能性があります。非表示のディレクトリを除外するには、それらを「exclude」リスト引数に追加します。 -
「**」ワイルドカードには 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",
],
...
)
experimental.txt を除く、ディレクトリ testdata 内のすべての 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_binary の srcs 属性を構成可能にします。各条件は、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 ファイルの直接の子孫であるサブパッケージと一致します。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」モジュールを使用することをおすすめします。