Bazel クエリ リファレンス

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。
問題を報告する ソースを表示

このページは、bazel query を使用してビルドの依存関係を分析するときに使用される Bazel クエリ言語のリファレンス マニュアルです。また、bazel query がサポートする出力形式についても説明します。

実際のユースケースについては、Bazel クエリの使用方法をご覧ください。

その他のクエリのリファレンス

読み込み後のフェーズ ターゲット グラフで実行される query に加えて、Bazel にはアクション グラフのクエリ構成可能なクエリが含まれています。

アクション グラフのクエリ

アクション グラフ クエリ(aquery)は、分析後の構成済みターゲット グラフで動作し、アクションアーティファクト、それらの関係に関する情報を公開します。aquery は、構成されたターゲット グラフから生成されたアクション/アーティファクトのプロパティを知りたい場合に便利です。たとえば、実際のコマンドの実行、入力、出力、ニーモニックなどです。

詳細については、aquery リファレンスをご覧ください。

構成可能なクエリ

従来の Bazel クエリは読み込み後のフェーズのターゲット グラフで実行されるため、構成とその関連コンセプトに関するコンセプトはありません。特に、select ステートメントは正しく解決されず、選択可能なすべての解像度が返されます。ただし、構成可能なクエリ環境 cquery は構成を適切に処理しますが、この元のクエリのすべての機能を提供しているわけではありません。

詳細については、cquery リファレンスをご覧ください。

bazel query の用途一般的な例を次に示します。

//foo ツリーが //bar/baz に依存しているのはなぜですか?経路を表示します。

somepath(foo/..., //bar/baz:all)

すべての C++ ライブラリで、foo_bin ターゲットが依存していない foo テストに依存していますか?

kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo:foo_bin))

トークン: 字句構文

クエリ言語の式は、次のトークンで構成されます。

  • キーワードlet など)。キーワードは言語の予約済み語です。以下で説明します。キーワードの完全なセットは次のとおりです。

  • 単語(「foo/...」、「.*test rule」、「//bar/baz:all」など)。文字シーケンスが「引用符」(単一引用符で始まって終了し、二重引用符で始まっている場合)です。文字シーケンスが引用符で囲まれていない場合でも、単語として解析されることがあります。引用符で囲まれていない単語は、アルファベットの A ~ Z、a ~ z、数字の 0 ~ 9、*/@.-_:$~[](アスタリスク、スラッシュ、アットマーク、ピリオド、ハイフン、アンダースコア、コロン、ドル記号、左角かっこ、右角かっこ)から描画された文字群です。ただし、引用符で囲まれていない単語は、ハイフン - またはアスタリスク * で始めることはできません。ただし、相対参照 [ターゲット名][/(concepts/labels#target-names)] はその文字で始めることができます。

    また、引用符で囲まれていない単語は、ターゲット名では使用できますが、+ 記号や = 記号とは使用できません。クエリ式を生成するコードを記述するときは、ターゲット名を引用符で囲む必要があります。

    ユーザー指定の値から Bazel クエリ式を作成するスクリプトを作成する際には、引用符が必要になります

     //foo:bar+wiz    # WRONG: scanned as //foo:bar + wiz.
     //foo:bar=wiz    # WRONG: scanned as //foo:bar = wiz.
     "//foo:bar+wiz"  # OK.
     "//foo:bar=wiz"  # OK.
    

    なお、この引用符は、シェルで必要となる次のような引用に追加するものです。

    bazel query ' "//foo:bar=wiz" '   # single-quotes for shell, double-quotes for Bazel.
    

    キーワードと演算子は、引用符で囲んで通常の単語として扱います。たとえば、some はキーワードですが、「some」は単語です。foo と「foo」はどちらも単語です。

    ただし、ターゲット名に一重引用符と二重引用符を使用する場合は注意が必要です。1 つ以上のターゲット名を引用符で囲む場合は、1 種類の引用符(すべてまたは二重引用符)のみを使用します。

    Java クエリ文字列の例を次に示します。

      'a"'a'         # WRONG: Error message: unclosed quotation.
      "a'"a"         # WRONG: Error message: unclosed quotation.
      '"a" + 'a''    # WRONG: Error message: unexpected token 'a' after query expression '"a" + '
      "'a' + "a""    # WRONG: Error message: unexpected token 'a' after query expression ''a' + '
      "a'a"          # OK.
      'a"a'          # OK.
      '"a" + "a"'    # OK
      "'a' + 'a'"    # OK
    

    この構文は、ほとんどの場合、引用符が不要になるようにしました。(通常でない)".*test rule" の例では引用符が必要です。ピリオドで始まり、スペースが含まれています。"cc_library" を引用する必要はありません。

  • 句読点(括弧 ()、ピリオド .、カンマ , など)。句読点を含む単語(上記の例外を除く)は引用符で囲む必要があります。

引用符で囲まれた単語の外の空白文字は無視されます。

Bazel クエリ言語のコンセプト

Bazel クエリ言語は式の言語です。すべての式は、ターゲットの部分的なセット、または同等のターゲットのグラフ(DAG)と評価されます。これが唯一のデータ型です。

セットとグラフは同じデータ型を参照しますが、データのさまざまな側面を強調します。次に例を示します。

  • 設定: ターゲットの一部の順序は考慮されません。
  • グラフ: ターゲットの部分的な順序は重要です。

依存関係グラフのサイクル

ビルド依存関係グラフは非巡回である必要があります。

クエリ言語で使用されるアルゴリズムは、非巡回グラフでの使用を想定していますが、サイクルに対して堅牢です。サイクルの処理方法は詳細に指定されていないため、信頼しないでください。

暗黙的な依存関係

BUILD ファイルで明示的に定義されているビルド依存関係に加えて、Bazel はルールに暗黙的な依存関係を追加します。たとえば、すべての Java ルールは暗黙的に JavaBuilder に依存します。暗黙的な依存関係は、$ で始まる属性を使用して設定され、BUILD ファイルでオーバーライドすることはできません。

デフォルトの bazel query では、クエリ結果を計算する際に、暗黙的な依存関係が考慮されます。この動作は、--[no]implicit_deps オプションで変更できます。クエリでは構成が考慮されないため、潜在的なツールチェーンは考慮されません。

Bazel クエリ言語式は、ビルド依存関係グラフ(すべての BUILD ファイル内のすべてのルール宣言によって暗黙的に定義されるグラフ)上で動作します。このグラフはやや抽象的であり、ビルドのすべてのステップを実行する方法の完全な説明を構成するものではないことを理解することが重要です。ビルドを実行するには、構成も必要です。詳細については、ユーザーガイドの構成セクションをご覧ください。

Bazel クエリ言語で式を評価する結果はすべての構成で true です。つまり、控えめな近似値であり、正確ではない可能性があります。たとえば、ビルド時に必要なソースファイルのセットをクエリツールで計算した場合、ビルドでこの機能を使用する必要はないものの、たとえばメッセージ変換をサポートするために必要なすべてのファイルがクエリツールに含まれるため、必要以上にレポートされる可能性があります。

グラフの順序の維持について

オペレーションは、そのサブ式から継承した順序の制約を保持します。これは、「部分的な注文保存の法則」と考えることができます。例を考えてみましょう。特定のターゲットの依存関係の推移的な終了を判断するクエリを発行すると、結果セットは依存関係グラフに従って順序付けされます。このセットをフィルタリングして file のターゲットのみを含めると、結果のサブセット内のすべてのターゲットに対して同じ推移的部分的順序関係が保持されます(これらのグラフは実際には元のグラフに直接接続されていません)。(ビルド依存関係グラフにはファイルファイル エッジはありません)。

ただし、すべての演算子が順序を保持する一方で、set オペレーションなどの一部のオペレーションでは、独自の順序指定制約が導入されません。以下の式を考えてみましょう。

deps(x) union y

最終結果セットの順序は、そのサブ式のすべての順序付きの制約を保証します。つまり、x のすべての推移的依存関係が互いに関して正しく順序付けられます。ただし、このクエリでは、y 内のターゲットの順序と、y 内のターゲットに対する deps(x) 内のターゲットの順序は保証されません(ただし、y にあるターゲットが deps(x) にある場合も除きます)。

順序の制約を導入する演算子には、allpathsdepsrdepssomepath、ターゲット パターンのワイルドカード package:*dir/... などがあります。

空のクエリ

スカイクエリは、指定されたユニバースのスコープで動作するクエリモードです。

SkyQuery のみで使用できる特殊関数

Sky クエリモードでは、allrdepsrbuildfiles というクエリ関数が追加されています。これらの関数はユニバースの範囲全体に対して機能します(そのため、通常のクエリには適しません)。

ユニバースのスコープを指定する

Sky クエリモードを有効にするには、--universe_scope または --infer_universe_scope の 2 つのフラグと --order_output=no を渡します。--universe_scope=<target_pattern1>,...,<target_patternN> は、ターゲット パターンで指定されたターゲット パターンの推移的なクロージャをプリロードするようクエリに指示します。これは、加算的またはサブトラクティブの両方です。すべてのクエリはこの「スコープ」内で評価されます。特に、allrdeps 演算子と rbuildfiles 演算子は、このスコープからの結果のみを返します。--infer_universe_scope は、クエリ式から --universe_scope の値を推測するよう Bazel に指示します。この推定値は、クエリ式内の一意のターゲット パターンのリストですが、これは必ずしも望ましいことではありません。例:

bazel query --infer_universe_scope --order_output=no "allrdeps(//my:target)"

このクエリ式の一意のターゲット パターンのリストは ["//my:target"] であるため、Bazel はこれを呼び出しと同様に扱います。

bazel query --universe_scope=//my:target --order_output=no "allrdeps(//my:target)"

ただし、--universe_scope を含むクエリの結果は //my:target のみで、構築によって //my:target の逆依存関係はありません。一方、以下を検討してください。

bazel query --infer_universe_scope --order_output=no "tests(//a/... + b/...) intersect allrdeps(siblings(rbuildfiles(my/starlark/file.bzl)))"

これは、定義に特定の .bzl ファイルが使用されるターゲットに推移的に依存するいくつかのディレクトリの下にあるターゲットの tests 展開でテスト ターゲットを計算しようとしている有意義なクエリ呼び出しです。ここで、--infer_universe_scope は、特に --universe_scope を選択する際にクエリ式を自分で解析する必要がある場合に便利です。

そのため、allrdepsrbuildfiles などのユニバース スコープの演算子を使用するクエリ式では、適切に動作する必要がある場合にのみ --infer_universe_scope を使用してください。

Sky Query にはデフォルトのクエリと比べて次のようなメリットがあります。主なデメリットは、出力をグラフの順序に従って並べ替えられないため、特定の出力形式が禁止されていることです。これには、デフォルトのクエリでは使用できない 2 つの演算子(allrdepsrbuildfiles)が使用できるというメリットがあります。また、Sky Query は、デフォルトの実装で生じる新しいグラフを作成するのではなく、Skyframe グラフをイントロスペクションすることでこの処理を行います。そのため、処理が速く、メモリ使用量が少ない場合があります。

式: 文法の構文とセマンティクス

これは、EBNF 表記で表現される Bazel クエリ言語の文法です。

expr ::= word
       | let name = expr in expr
       | (expr)
       | expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr
       | set(word *)
       | word '(' int | word | expr ... ')'

以降のセクションでは、この文法の各処理を順番に説明します。

ターゲット パターン

expr ::= word

構文的には、ターゲット パターンは単語です。これは、(順序付けされていない)ターゲットのセットとして解釈されます。最も単純なターゲット パターンは、単一のターゲット(ファイルまたはルール)を識別するラベルです。たとえば、ターゲット パターン //foo:bar は、1 つの要素であるターゲット bar ルールを含むセットとして評価されます。

ターゲット パターンでは、パッケージとターゲットにワイルドカードを含めるためにラベルが一般化されます。たとえば、foo/...:all(または単に foo/...)は、foo ディレクトリの下にあるすべてのパッケージのルールを含むセットに評価されるターゲット パターンです。bar/baz:all は、bar/baz パッケージのすべてのルールを含むセットを評価するが、サブパッケージは評価しないターゲット パターンです。

同様に、foo/...:* は、foo ディレクトリ内のすべてのターゲット(ルールとファイル)を再帰的に含むセットを評価するターゲット パターンです。bar/baz:* は、bar/baz パッケージ内のすべてのターゲットを含むセットを評価しますが、サブパッケージは評価しません。

ワイルドカード :* は、ルールだけでなくファイルと一致するため、:all よりも有用です。逆に、:all ワイルドカード(foo/... などのターゲット パターンでは暗黙的)は、通常、ビルドに役立ちます。

bazel query ターゲット パターンは、bazel build ビルド ターゲットと同じように機能します。詳細については、ターゲット パターンまたは bazel help target-syntax を入力してください。

ターゲット パターンは、シングルトン セット(ラベルの場合)や多数の要素を含むセット(数千の要素を含む foo/... など)に評価することも、ターゲット パターンがターゲットに一致しない場合は空のセットとして評価することもできます。

ターゲット パターン式の結果に含まれるすべてのノードは、依存関係の関係に従って相互に正しく順序付けられます。したがって、foo:* の結果は、パッケージ foo 内のターゲット セットだけでなく、それらのターゲットのグラフにもなります。(結果ノードと他のノードとの相対的な順序は保証されません)。詳細については、グラフの順序をご覧ください。

Variables

expr ::= let name = expr1 in expr2
       | $name

Bazel クエリ言語では、変数の定義と参照が可能です。let 式の評価結果は expr2 の場合と同じで、変数 name の無料出現はすべて expr1 の値に置き換えられます。

たとえば、let v = foo/... in allpaths($v, //common) intersect $vallpaths(foo/...,//common) intersect foo/... と同じです。

囲んでいる let name = ... 式以外の変数参照 name はエラーになります。つまり、トップレベルのクエリ式に自由変数を含めることはできません。

上記の文法の本番環境では、nameword に似ていますが、C プログラミング言語の有効な識別子であるという追加の制約があります。変数への参照の先頭には「$」を付けます。

let 式は 1 つの変数のみを定義しますが、ネストできます。

ターゲット パターンと変数参照はどちらも単一のトークン、1 つの単語で構成されているため、構文の曖昧さが発生します。ただし、セマンティックな曖昧さはありません。正当な変数名である単語のサブセットは、有効なターゲット パターンである単語のサブセットと重複しないためです。

技術的には、let 式は、クエリ言語の表現性を高めません。クエリなしで表現可能なクエリはすべて表現できます。ただし、多くのクエリの簡潔さが改善され、より効率的なクエリ評価につながる可能性があります。

かっこで囲まれた式

expr ::= (expr)

かっこによってサブ式が関連付けられて、評価の順序が強制されます。かっこで囲まれた式は、引数の値に評価されます。

代数集合演算: 積、和、差

expr ::= expr intersect expr
       | expr ^ expr
       | expr union expr
       | expr + expr
       | expr except expr
       | expr - expr

これら 3 つの演算子は、引数に対して通常の set オペレーションを計算します。 各演算子には、intersect などの名詞形式と、^ などのシンボリック形式があります。どちらの形式も同等です。記号形式の方が入力が簡単です。(わかりやすくするために、このページの残りの部分では公称形式を使用します)。

次に例を示します。

foo/... except foo/bar/...

foo/... に一致するものの foo/bar/... には一致しないターゲットのセットに評価されます。

同じクエリを次のように記述できます。

foo/... - foo/bar/...

intersect^)と union+)のオペレーションは可換です(対称)。except-)は非対称です。パーサーは 3 つの演算子をすべて左結合と等価なものとして扱うため、丸かっこを使用することをおすすめします。たとえば、最初の 2 つの式は同等ですが、3 番目の式は同じではありません。

x intersect y union z
(x intersect y) union z
x intersect (y union z)

外部ソースからのターゲットの読み取り: 設定

expr ::= set(word *)

set(a b c ...) 演算子は、ゼロ個以上のターゲット パターンの集合を空白文字で区切って計算します(カンマなし)。

Bourne シェルの $(...) 機能と組み合わせて、set() では、1 つのクエリの結果を通常のテキスト ファイルに保存し、他のプログラム(標準の UNIX シェルツールなど)を使用してそのテキスト ファイルを操作し、さらなる処理の値としてクエリツールに結果を導入できます。例:

bazel query deps(//my:target) --output=label | grep ... | sed ... | awk ... > foo
bazel query "kind(cc_binary, set($(<foo)))"

次の例では、awk プログラムを使用して maxrank 値をフィルタすることで kind(cc_library, deps(//some_dir/foo:main, 5)) を計算しています。

bazel query 'deps(//some_dir/foo:main)' --output maxrank | awk '($1 < 5) { print $2;} ' > foo
bazel query "kind(cc_library, set($(<foo)))"

以下の例では、$(<foo)$(cat foo) の省略形ですが、前の awk コマンドなど、cat 以外のシェルコマンドも使用できます。

関数

expr ::= word '(' int | word | expr ... ')'

クエリ言語では複数の関数が定義されています。関数の名前によって、必要な引数の数と型が決まります。次の関数を使用できます。

依存関係の一時的な終了: 依存関係

expr ::= deps(expr)
       | deps(expr, depth)

deps(x) 演算子は、引数セット x の依存関係の推移的な終了によって形成されたグラフを評価します。たとえば、deps(//foo) の値は、すべての依存関係を含む単一ノード foo に基づく依存関係グラフです。deps(foo/...) の値は依存関係グラフです。ルートは、foo ディレクトリの下にあるすべてのパッケージのすべてのルールです。ここで「dependencies」はルールとファイルのターゲットのみを意味するため、これらのターゲットの作成に必要な BUILD ファイルと Starlark ファイルはここに含まれていません。そのためには、buildfiles 演算子を使用します。

結果のグラフは、依存関係の関係に従って並べ替えられます。詳しくは、グラフの順序のセクションをご覧ください。

deps 演算子はオプションの 2 番目の引数を受け入れます。これは、検索深度の上限を示す整数リテラルです。deps(foo:*, 0)foo パッケージ内のすべてのターゲットを返しますが、deps(foo:*, 1) には foo パッケージ内の任意のターゲットの直接の前提条件がさらに含まれます。deps(foo:*, 2) には、deps(foo:*, 1) のノードから直接到達可能なノードがさらに含まれます。(これらの数値は、minrank の出力形式で示されるランクに対応しています)。depth パラメータを省略すると、検索は無制限になり、前提条件の再帰的終了が計算されます。

リバース依存関係の一時的な終了: rdeps

expr ::= rdeps(expr, expr)
       | rdeps(expr, expr, depth)

rdeps(u, x) 演算子は、ユニバース セット u の推移的なクロージャ内で、引数セット x の逆依存関係を評価します。

結果のグラフは、依存関係の関係に従って並べ替えられます。詳細については、グラフの順序のセクションをご覧ください。

rdeps 演算子はオプションの 3 番目の引数を受け入れます。これは、検索深度の上限を示す整数リテラルです。結果のグラフには、引数セット内の任意のノードから、指定した奥行きの距離にあるノードのみが含まれます。rdeps(//foo, //common, 1) は、//common に直接依存する //foo の推移的クロージャ内のすべてのノードを評価します。(これらの数値は、minrank の出力形式に表示されるランクに対応しています)。depth パラメータを省略すると、検索は無制限になります。

すべての逆依存関係の一時的な終了: allrdeps

expr ::= allrdeps(expr)
       | allrdeps(expr, depth)

allrdeps 演算子は rdeps 演算子と同じように動作しますが、「ユニバース セット」は --universe_scope フラグが個別に評価されるのではなく、評価されるものです。したがって、--universe_scope=//foo/... が渡された場合、allrdeps(//bar)rdeps(//foo/..., //bar) と同等になります。

同じパッケージ内の直接依存関係(same_pkg_direct_rdeps)

expr ::= same_pkg_direct_rdeps(expr)

same_pkg_direct_rdeps(x) 演算子は、引数セット内のターゲットと同じパッケージ内にあり、それに直接依存するターゲットの完全なセットを評価します。

ターゲットのパッケージを処理する: 兄弟姉妹

expr ::= siblings(expr)

siblings(x) 演算子は、引数セット内のターゲットと同じパッケージにあるターゲットの完全なセットを評価します。

任意の選択: 一部

expr ::= some(expr)
       | some(expr, count )

some(x, k) 演算子は、引数セット x から任意に k 個のターゲットを選択し、これらのターゲットのみを含むセットを評価します。パラメータ k は省略可能です。存在しない場合は、任意の 1 つのターゲットのみを含むシングルトン セットが返されます。引数セット x のサイズが k より小さい場合は、引数セット x 全体が返されます。

たとえば、式 some(//foo:main union //bar:baz) は、//foo:main または //bar:baz のいずれかを含むシングルトン セットとして評価されますが、その定義はありません。式 some(//foo:main union //bar:baz, 2) または some(//foo:main union //bar:baz, 3) は、//foo:main//bar:baz の両方を返します。

引数がシングルトンの場合、some は恒等関数を計算します。some(//foo:main)//foo:main と同等です。

some(//foo:main intersect //bar:baz) 式のように、指定された引数セットが空の場合はエラーになります。

パス演算子: somepath、allpaths

expr ::= somepath(expr, expr)
       | allpaths(expr, expr)

somepath(S, E) 演算子と allpaths(S, E) 演算子は、2 つのターゲット セット間のパスを計算します。どちらのクエリも、2 つの引数を受け取り、開始点の S セットと終了点のセット E を受け入れます。somepath は、S 内のターゲットから E 内のターゲットへの任意のパス上のノードのグラフを返します。allpaths は、S 内の任意のターゲットから E 内の任意のターゲットへのすべてのパス上のノードのグラフを返します。

結果のグラフは、依存関係の関係に従って並べ替えられます。詳しくは、グラフの順序のセクションをご覧ください。

一部のパス
somepath(S1 + S2, E)。考えられる 1 つの結果です。
一部のパス
somepath(S1 + S2, E)
Allpaths
allpaths(S1 + S2, E)

ターゲットの種類でのフィルタリング: kind

expr ::= kind(word, expr)

kind(pattern, input) 演算子は、一連のターゲットにフィルタを適用し、想定されていない種類のターゲットを破棄します。pattern パラメータは、照合するターゲットの種類を指定します。

たとえば、BUILD パッケージ(p パッケージ用)で定義された 4 つのターゲットの種類を次の表に示します。

コード ターゲット 種類
        genrule(
            name = "a",
            srcs = ["a.in"],
            outs = ["a.out"],
            cmd = "...",
        )
      
//p:a genrule ルール
//p:a.in ソースファイル
//p:a.out 生成されたファイル
//p:BUILD ソースファイル

したがって、kind("cc_.* rule", foo/...)foo の下にあるすべての cc_librarycc_binary などのルール ターゲットのセットに評価され、kind("source file", deps(//foo))//foo ターゲットの依存関係の推移的クロージャにあるすべてのソースファイルのセットに評価されます。

pattern 引数は、引用符(source file.*_test など)の多くがパーサーによって単語とみなされないため、多くの場合、引用符で囲む必要があります。

package group で一致した場合、:all で終わるターゲットは結果を生成しません。:all-targets を代わりに使用してください。

ターゲット名のフィルタリング: フィルタ

expr ::= filter(word, expr)

filter(pattern, input) 演算子は一連のターゲットにフィルタを適用し、ラベル(絶対形式)がパターンに一致しないターゲットを破棄して、入力のサブセットに評価します。

最初の引数 pattern は、ターゲット名に対する正規表現を含む単語です。filter 式は、x がセット input のメンバーであり、x のラベル(絶対形、//foo:bar など)に正規表現 pattern の(非アンカー)一致が含まれるように、すべてのターゲット x を含むセットを評価します。すべてのターゲット名は // で始まっているため、^ 正規表現アンカーの代わりに使用できます。

この演算子は、intersect 演算子の代わりにはるかに高速で堅牢な選択肢を提供することがよくあります。たとえば、//foo:foo ターゲットのすべての bar 依存関係を確認するには、

deps(//foo) intersect //bar/...

ただし、このステートメントでは bar ツリー内のすべての BUILD ファイルの解析が必要になります。そのため、処理が遅くなり、無関係な BUILD ファイル内のエラーが発生しやすくなります。代替手段:

filter(//bar, deps(//foo))

最初に //foo 依存関係のセットを計算し、指定されたパターンに一致するターゲット(つまり、名前が //bar を部分文字列として含むターゲット)のみをフィルタリングします。

filter(pattern, expr) 演算子は、名前や拡張子で特定のファイルを絞り込む場合にもよく使用されます。次に例を示します。

filter("\.cc$", deps(//foo))

//foo のビルドに使用されるすべての .cc ファイルのリストが提供されます。

ルール属性のフィルタリング: attr

expr ::= attr(word, word, expr)

attr(name, pattern, input) 演算子は一連のターゲットにフィルタを適用し、ルール以外のターゲット、属性 name が定義されていないルール ターゲット、指定された正規表現 pattern と属性値が一致しないルール ターゲットを破棄します。この条件は、入力のサブセットに評価されます。

最初の引数 name は、指定された正規表現パターンと照合する必要があるルール属性の名前です。2 番目の引数 pattern は、属性値の正規表現です。attr 式は、すべてのターゲット x を含むセットを評価します。たとえば、x はセット input のメンバーであり、属性 name は定義済みの属性です。属性値には正規表現 pattern の(アンカーされていない)一致が含まれています。name がオプションの属性であり、ルールで明示的に指定されていない場合は、デフォルトの属性値が比較に使用されます。次に例を示します。

attr(linkshared, 0, deps(//foo))

linkshared 属性を持つすべての //foo 依存関係(cc_binary ルールなど)を選択し、明示的に 0 に設定するか、まったく設定しないが、デフォルト値の 0(cc_binary ルールなど)に設定します。

リスト型の属性(srcsdata など)は [value<sub>1</sub>, ..., value<sub>n</sub>] 形式の文字列に変換されます。[ 角かっこと ] 括弧で囲み、,、カンマ、スペースを使用して、複数の値を区切ります。ラベルは、ラベルの絶対形式を使用して文字列に変換されます。たとえば、属性 deps=[":foo", "//otherpkg:bar", "wiz"] は文字列 [//thispkg:foo, //otherpkg:bar, //thispkg:wiz] に変換されます。 角かっこは常に存在するため、空のリストでは一致のために文字列値 [] が使用されます。次に例を示します。

attr("srcs", "\[\]", deps(//foo))

srcs 属性が空である //foo 依存関係の中からすべてのルールを選択します。

attr("data", ".{3,}", deps(//foo))

data 属性の値を少なくとも 1 つ指定する //foo 依存関係の中で、すべてのルールを選択します(//: のため、すべてのラベルは 3 文字以上です)。

list-type 属性で特定の value を持つ //foo 依存関係内のすべてのルールを選択するには、次のコマンドを使用します。

attr("tags", "[\[ ]value[,\]]", deps(//foo))

これは、value 前の文字が [ またはスペースになり、value 後の文字がカンマまたは ] になるためです。

ルールの公開設定のフィルタ: 表示

expr ::= visible(expr, expr)

visible(predicate, input) 演算子は、一連のターゲットにフィルタを適用し、必要な可視性なしでターゲットを破棄します。

最初の引数 predicate は、出力内のすべてのターゲットを表示する必要があるターゲットのセットです。visible 式は、x がセット input のメンバーであるように、すべてのターゲット x を含むセットを評価し、predicate x 内のすべてのターゲット yy から見えるようにします。例:

visible(//foo, //bar:*)

パッケージ //bar で、可視性の制限に違反することなく //foo が依存できるすべてのターゲットを選択します。

ラベルタイプのラベル属性の評価: labels

expr ::= labels(word, expr)

labels(attr_name, inputs) 演算子は、セット inputs 内のルールで、属性 attr_name の属性「label」または「label list」に指定されたターゲットのセットを返します。

たとえば、labels(srcs, //foo) は、//foo ルールの srcs 属性に出現するターゲットのセットを返します。inputssrcs 属性が設定されたルールが複数ある場合、それらの srcs の結合が返されます。

test_suites を開いてフィルタする: テスト

expr ::= tests(expr)

tests(x) 演算子はセット x 内のすべてのテストルールのセットを返し、任意の test_suite ルールを参照する個々のテストのセットに展開し、tagsize でフィルタリングを適用します。

デフォルトでは、クエリの評価では、すべての test_suite ルールのテスト対象以外のターゲットが無視されます。これは --strict_test_suite オプションでエラーに変更できます。

たとえば、kind(test, foo:*) クエリでは、foo パッケージのすべての *_test ルールと test_suite ルールが一覧表示されます。すべての結果は(定義により)foo パッケージのメンバーです。一方、クエリ tests(foo:*) は、bazel test foo:* によって実行される個々のテストをすべて返します。これには、test_suite ルールを介して直接的または間接的に参照される他のパッケージに属するテストが含まれることがあります。

パッケージ定義ファイル: buildfiles

expr ::= buildfiles(expr)

buildfiles(x) 演算子は、セット x 内の各ターゲットのパッケージを定義するファイルのセットを返します。つまり、パッケージごとに、その BUILD ファイルと、load を介して参照するすべての .bzl ファイルを返します。また、これらの load ファイルが格納されているパッケージの BUILD ファイルも返されることに注意してください。

この演算子は通常、指定されたターゲットのビルドに必要なファイルまたはパッケージを決定するときに使用されます。多くの場合、この演算子は以下の --output package オプションと組み合わせて使用されます。次に例を示します。

bazel query 'buildfiles(deps(//foo))' --output package

//foo が推移的に依存するすべてのパッケージのセットを返します。

パッケージ定義ファイル: rbuildfiles

expr ::= rbuildfiles(word, ...)

rbuildfiles 演算子は、パスフラグメントのカンマ区切りのリストを受け取り、これらのパスフラグメントに推移的に依存する BUILD ファイルのセットを返します。たとえば、//foo がパッケージの場合、rbuildfiles(foo/BUILD)//foo:BUILD ターゲットを返します。foo/BUILD ファイルに load('//bar:file.bzl'... が含まれている場合、rbuildfiles(bar/file.bzl)//foo:BUILD ターゲットと、//bar:file.bzl を読み込む他の BUILD ファイルのターゲットを返します。

rbuildfiles 演算子のスコープは、--universe_scope フラグで指定されたユニバースです。BUILD ファイルと .bzl ファイルに直接対応していないファイルは結果に影響しません。たとえば、ソースファイル(foo.cc など)は、BUILD ファイルで明示的に指定されている場合でも無視されます。ただし、シンボリック リンクが尊重されるため、foo/BUILDbar/BUILD へのシンボリック リンクである場合、rbuildfiles(bar/BUILD) は結果に //foo:BUILD を含めます。

rbuildfiles 演算子は、ほぼ buildfiles 演算子の逆です。しかし、この倫理的反転は一方向に強くなっています。rbuildfiles の出力は buildfiles の入力に似ています。前者はパッケージ内に BUILD ファイル ターゲットのみを持ち、後者はそのようなターゲットを含む可能性があります。逆に、対応が弱い。buildfiles 演算子の出力は、すべてのパッケージと .bzl: 特定の入力に必要なファイル。ただし、rbuildfiles 演算子の入力はターゲットではなく、ターゲットに対応するパスフラグメントになります。

パッケージ定義ファイル: loadfiles

expr ::= loadfiles(expr)

loadfiles(x) 演算子は、セット x 内の各ターゲットのパッケージの読み込みに必要な Starlark ファイルのセットを返します。つまり、パッケージごとに、BUILD ファイルから参照されている .bzl ファイルを返します。

出力形式

bazel query はグラフを生成します。--output コマンドライン オプションを使用して、このグラフを表示するコンテンツ、形式、順序を指定します。bazel query

Sky Query で実行する場合、順序付けされた出力と互換性のある出力形式のみが許可されます。具体的には、graphminrankmaxrank の出力形式は禁止されています。

一部の出力形式は追加オプションを受け入れます。各出力オプションの名前には、それが適用される出力形式が接頭辞として付加されるため、--graph:factored は、--output=graph が使用されている場合にのみ適用されます。graph 以外の出力形式が使用されている場合、影響はありません。同様に、--xml:line_numbers--output=xml が使用されている場合にのみ適用されます。

結果の優先順位

クエリ式は常にグラフ順序の保存法に従いますが、結果の表示は、依存順序または順序なしのいずれかで行うことができます。これは、結果セットのターゲットやクエリの計算方法には影響しません。影響を受けるのは stdout への結果の出力のみです。また、依存関係の順序と同等のノードはアルファベット順に並べられる場合とされない場合があります。この動作を制御するには、--order_output フラグを使用します。(--[no]order_results フラグには --order_output フラグの機能のサブセットがあり、非推奨です)。

このフラグのデフォルト値は auto で、辞書順で結果を出力します。ただし、somepath(a,b) を使用すると、代わりに deps の順序で結果が出力されます。

このフラグが no で、--outputbuildlabellabel_kindlocationpackageprotoxml のいずれかである場合、出力は任意の順序で出力されます。通常、これが最速のオプションです。ただし、--outputgraphminrankmaxrank のいずれかである場合はサポートされません。これらの形式では、Bazel は常に依存関係の順序またはランクで並べ替えられた結果を出力します。

このフラグが deps の場合、Bazel は結果をトポロジの順(つまり、依存関係)に出力します。ただし、依存関係の順序で順序付けされていないノード(どちらか一方から他方へのパスがないため)は、任意の順序で出力できます。

このフラグが full の場合、Bazel はノードを確定的な(合計)順序で出力します。まず、すべてのノードがアルファベット順に表示されます。次に、リスト内の各ノードは、アクセスされていないノードへの送信エッジを後続ノードのアルファベット順で走査する、注文後深度優先検索の開始として使用されます。最後に、ノードはアクセスされた順序とは逆の順序で出力されます。

この順序でのノードの表示は遅くなる可能性があるため、決定論が重要な場合にのみ使用してください。

ビルド時に表示されるターゲットのソース形式を出力します

--output build

このオプションでは、各ターゲットは BUILD 言語で手書きされたものとみなされます。すべての変数と関数呼び出し(glob、マクロなど)が展開されるため、Starlark マクロの効果を確認できます。また、有効なルールごとに、generator_namegenerator_function の値も報告されます。この値は、有効なルールを生成するために評価されたマクロの名前を示します。

出力には BUILD ファイルと同じ構文が使用されますが、有効な BUILD ファイルを生成する保証はありません。

--output label

このオプションでは、結果のグラフの各ターゲットの名前(またはラベル)が、トポロジごとに順番に 1 行に 1 つずつラベルとして出力されます(--noorder_results が指定されている場合を除く。結果の順序に関する注記)をご覧ください。(トポロジの順序は、グラフのノードがすべての後続ノードよりも早く表示される順序です)。もちろん、グラフのトポロジの順序は多数ありますが(逆順は 1 つだけです)、どれが選択されるかは指定されません。

somepath クエリの出力を印刷する場合、ノードが出力される順序は、パスの順序になります。

注意: 場合によっては、同じラベルを持つ 2 つの異なるターゲットが存在することがあります。たとえば、sh_binary ルールとその唯一の(暗黙的な)srcs ファイルが foo.sh と呼ばれる場合があります。クエリの結果にこれらのターゲットが両方含まれている場合、出力(label 形式)に重複するものが表示されます。label_kind の形式を使用すると、2 つのターゲットが同じ名前で、一方が種類 sh_binary rule、もう一方が source file という区別が明確になります。

--output label_kind

label と同様に、この出力形式では、結果グラフの各ターゲットのラベルがトポロジ順に出力されますが、ターゲットの kind がラベルの前に付加されます。

--output minrank --output maxrank

label と同様に、minrankmaxrank の出力形式には、結果グラフの各ターゲットのラベルが出力されます。ただし、トポロジ順に表示されるのではなく、ランク順順に表示されます。結果の順序 --[no]order_results フラグは影響を受けません(結果の順序に関する注記を参照)。

この形式には 2 つのバリアントがあり、minrank は、ルートノードからそのノードへの最短パスの長さで各ノードをランク付けします。「ルート」ノード(受信エッジがないノード)はランク 0 であり、後続ノードはランク 1 になります(このように、エッジはターゲットからその前提条件(依存するターゲット)を指します)。

maxrank は、ルートノードからノードまでの最長パスの長さで各ノードをランク付けします。この場合も、「ルート」のランクは 0 であり、他のすべてのノードのランクは、前のすべてのノードの最大ランクよりも 1 つ大きいランクです。

サイクル内のすべてのノードは同じランクと見なされます。(ほとんどのグラフは非巡回ですが、BUILD ファイルには生理周期に誤りがあるため、単に生じます)。

これらの出力形式は、グラフの深さを検出するのに役立ちます。deps(x)rdeps(x)、または allpaths クエリの結果に使用されている場合、ランク番号は、x からそのランクのノードまでの最短パス(minrank を含む)または最長パス(maxrank あり)と等しくなります。maxrank を使用すると、ターゲットのビルドに必要なビルドステップの最長シーケンスを特定できます。

たとえば、--output minrank--output maxrank がそれぞれ指定された場合、左側のグラフは右側の出力を生成します。

上位
      minrank

      0 //c:c
      1 //b:b
      1 //a:a
      2 //b:b.cc
      2 //a:a.cc
      
      maxrank

      0 //c:c
      1 //b:b
      2 //a:a
      2 //b:b.cc
      3 //a:a.cc
      
--output location

このオプションは、label_kind と同様に、結果の各ターゲットについて、出力対象の種類とラベルを出力しますが、接頭辞としてターゲットの場所を表す文字列をファイル名と行番号として付加します。形式は grep の出力に似ています。したがって、後者を解析できるツール(Emacs や vi など)も、クエリ出力を使用して一連の一致をステップ実行し、Bazel クエリツールを依存関係グラフ認識の「BUILD ファイル用の grep」として使用できます。

位置情報はターゲットの種類によって異なります(kind 演算子をご覧ください)。ルールの場合、BUILD ファイルでルールの宣言の場所が出力されます。ソースファイルの場合は、実際のファイルの場所の 1 行目が出力されます。生成されたファイルの場合は、それを生成したルールの場所が出力されます。(クエリツールには、生成されたファイルの実際の場所を見つけるための十分な情報がありません。また、いずれの場合も、ビルドがまだ実行されていない場合は存在しない可能性があります)。

--output package

このオプションは、結果セット内のターゲットが属するすべてのパッケージの名前を出力します。名前は辞書順で出力されます。重複するものは除外されます。正式には、これは一連のラベル(パッケージ、ターゲット)からパッケージに投影されます。

外部リポジトリのパッケージは @repo//foo/bar の形式であり、メイン リポジトリのパッケージは foo/bar です。

この出力オプションを deps(...) クエリと組み合わせて使用すると、特定のターゲット セットをビルドするためにチェックアウトする必要があるパッケージのセットを検出できます。

結果のグラフを表示します。

--output graph

このオプションを使用すると、クエリ結果が一般的な AT&T GraphViz 形式の有向グラフとして出力されます。通常、結果は .png.svg などのファイルに保存されます。(dot プログラムがワークステーションにインストールされていない場合は、sudo apt-get install graphviz コマンドを使用してインストールできます。)呼び出しの例は、下記のサンプルのセクションをご覧ください。

この出力形式は、allpathsdepsrdeps クエリに特に有効です。これらの結果には、--output label のように線形形式でレンダリングしたときに簡単に可視化できない一連のパスが含まれる。

デフォルトでは、グラフは因数分解形式でレンダリングされます。つまり、トポロジで同等のノードは、複数のラベルを持つ単一のノードにマージされます。一般的な結果グラフは反復的なパターンを多く含むため、グラフがコンパクトで読みやすくなります。たとえば、java_library ルールは、同じ genrule によって生成される数百の Java ソースファイルに依存している場合があります。因数グラフでは、これらのファイルはすべて 1 つのノードで表されます。この動作は、--nograph:factored オプションを使用して無効にできます。

--graph:node_limit n

このオプションでは、出力のグラフノードのラベル文字列の最大長を指定します。長いラベルは切り捨てられます。-1 を指定すると、切り捨てられます。通常、グラフが印刷される因数分解フォームにより、ノードラベルが非常に長くなる場合があります。GraphViz は、このオプションのデフォルト値である 1, 024 文字を超えるラベルを処理できません。--output=graph を使用している場合を除き、このオプションは無効です。

--[no]graph:factored

デフォルトでは、上記のように、グラフは因数の形式で表示されます。--nograph:factored を指定すると、因数なしでグラフが出力されます。GraphViz を使用した可視化は実用的ではありませんが、シンプルな形式であれば他のツール(grep など)による処理が容易になる場合があります。--output=graph を使用している場合を除き、このオプションは無効です。

XML

--output xml

このオプションを使用すると、結果のターゲットが XML 形式で出力されます。出力は次のような XML ヘッダーで始まります。

  <?xml version="1.0" encoding="UTF-8"?>
  <query version="2">

次に、結果グラフの各ターゲットの XML 要素をトポロジ順(順序付けされていない結果がリクエストされた場合を除き)続行し、終了に終了します。

</query>

file 型のターゲットに対しては、単純なエントリが出力されます。

  <source-file name='//foo:foo_main.cc' .../>
  <generated-file name='//foo:libfoo.so' .../>

ただし、ルールの場合は XML が構造化され、ルールのすべての属性の定義が含まれます。定義には、ルールの BUILD ファイルで値が明示的に指定されていない属性も含まれます。

また、結果には rule-input 要素と rule-output 要素が含まれるため、たとえば、srcs 属性の要素は前方依存関係(前提条件)であり、outs 属性の内容が後方依存関係(コンシューマー)であることを認識せずに、依存関係グラフのトポロジを再構成できます。

--noimplicit_deps が指定されている場合、暗黙的な依存関係rule-input 要素は抑制されています。

  <rule class='cc_binary rule' name='//foo:foo' ...>
    <list name='srcs'>
      <label value='//foo:foo_main.cc'/>
      <label value='//foo:bar.cc'/>
      ...
    </list>
    <list name='deps'>
      <label value='//common:common'/>
      <label value='//collections:collections'/>
      ...
    </list>
    <list name='data'>
      ...
    </list>
    <int name='linkstatic' value='0'/>
    <int name='linkshared' value='0'/>
    <list name='licenses'/>
    <list name='distribs'>
      <distribution value="INTERNAL" />
    </list>
    <rule-input name="//common:common" />
    <rule-input name="//collections:collections" />
    <rule-input name="//foo:foo_main.cc" />
    <rule-input name="//foo:bar.cc" />
    ...
  </rule>

ターゲットのすべての XML 要素には、ターゲットのラベルである name 属性と、--output location によって出力されるターゲットの場所の値である location 属性が含まれます。

--[no]xml:line_numbers

デフォルトでは、XML 出力に表示される場所には行番号が含まれています。 --noxml:line_numbers を指定すると、行番号は出力されません。

--[no]xml:default_values

デフォルトでは、XML 出力には、その種類の属性のデフォルト値であるルール属性は含まれません(たとえば、BUILD ファイルで指定されていない場合や、デフォルト値が明示的に指定された場合)。このオプションを使用すると、このような属性値が XML 出力に含まれます。

正規表現

クエリ言語の正規表現では Java 正規表現ライブラリを使用するため、java.util.regex.Pattern の完全な構文を使用できます。

外部リポジトリを使用したクエリ

ビルドが(WORKSPACE ファイルで定義される)外部リポジトリのルールに依存している場合、クエリ結果にはこれらの依存関係が含まれます。たとえば、//foo:bar//external:some-lib に依存し、//external:some-lib@other-repo//baz:lib にバインドされている場合、bazel query 'deps(//foo:bar)'@other-repo//baz:lib//external:some-lib の両方を依存関係としてリストします。

外部リポジトリ自体はビルドの依存関係ではありません。つまり、上記の例では、//external:other-repo は依存関係ではありません。ただし、次のように //external パッケージのメンバーとしてクエリできます。

  # Querying over all members of //external returns the repository.
  bazel query 'kind(http_archive, //external:*)'
  //external:other-repo

  # ...but the repository is not a dependency.
  bazel query 'kind(http_archive, deps(//foo:bar))'
  INFO: Empty results