目次
パッケージ
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 |
ラベルのリスト。デフォルトは このパッケージのトップレベルのルール ターゲットとシンボリック マクロのデフォルトの公開設定。つまり、シンボリック マクロ内で宣言されていないターゲットとシンボリック マクロです。ターゲットまたはマクロで この属性の構文について詳しくは、 公開設定のドキュメントをご覧ください。パッケージのデフォルトの公開設定は、デフォルトで公開されている 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 つ以上のパッケージ グループで記述されたパッケージへのアクセスを許可できます。公開設定システムの詳細については、公開設定属性をご覧ください。
特定のパッケージがグループに属すると見なされるのは、そのパッケージが 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/**
は、パッケージの最初のレベルのサブディレクトリfoo/
の下にあるサブパッケージ以外のすべてのサブディレクトリ内のすべてのファイルに一致します。exclude_directories
が 0 に設定されている場合、foo
ディレクトリ自体もパターンに一致します。この場合、**
はゼロのパスセグメントに一致します。**/a.txt
は、このパッケージのディレクトリ内のa.txt
ファイルと、サブパッケージ以外のサブディレクトリ内のa.txt
ファイルと一致します。**/bar/**/*.txt
は、結果パスのディレクトリの少なくとも 1 つがbar
と呼ばれている場合(**
はゼロ セグメントにも一致します)、このパッケージのサブパッケージ以外のすべてのサブディレクトリ内のすべての.txt
ファイルに一致します。xxx/bar/yyy/zzz/a.txt
、bar/a.txt
、bar/zzz/a.txt
など**
は、このパッケージのサブパッケージ以外のすべてのサブディレクトリ内のすべてのファイルに一致します。foo**/a.txt
は、**
がセグメントとして単独で存在する必要があるため、無効なパターンです。/
の後に定義された 2 番目のセグメントが空の文字列であるため、foo/
は無効なパターンです。
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
または package-path の他の場所)として存在する場合、x/y/z.cc
は含まれません。つまり、glob 式の結果は実際には BUILD ファイルの存在に依存します。つまり、x/y
というパッケージが存在しない場合や、--deleted_packages フラグを使用して削除済みとしてマークされている場合、同じ glob 式にx/y/z.cc
が含まれます。 - 上記の制限は、使用するワイルドカードに関係なく、すべての glob 式に適用されます。
-
ファイル名が
.
で始まる隠しファイルは、**
ワイルドカードと*
ワイルドカードの両方に完全に一致します。隠しファイルを複合パターンと照合する場合は、パターンの先頭を.
にする必要があります。たとえば、*
と.*.txt
は.foo.txt
と一致しますが、*.txt
は一致しません。非表示のディレクトリも同様に照合されます。非表示のディレクトリには、入力として必要のないファイルが含まれている可能性があります。また、不要なグルーピング ファイルの数とメモリ消費量が増加する可能性があります。非表示のディレクトリを除外するには、それらを「除外」リスト引数に追加します。 -
「**」ワイルドカードには 1 つの特殊なケースがあります。パターン
"**"
がパッケージのディレクトリパスと一致しないケースです。つまり、glob(["**"], exclude_directories = 0)
は、現在のパッケージのディレクトリの下にあるすべてのファイルとディレクトリと厳密に、転送で一致します(ただし、サブパッケージのディレクトリには入りません。この点については、前述の注記をご覧ください)。
一般に、グロブパターンに単なる「*」を使用するのではなく、適切な拡張子(*.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( {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 ファイルの直接子孫であるサブパッケージと一致できます。包含パターンと除外パターンの詳細な説明と例については、glob をご覧ください。返されるサブパッケージのリストは昇順で並べられ、
exclude
ではなくinclude
の指定されたパターンに一致する、現在の読み込みパッケージを基準としたパスが含まれます。例
次の例では、パッケージ
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」モジュールを使用することをおすすめします。