cquery
は、query
のバリアントで、
select()
とビルド オプションビルドへの影響
表示されます。
Bazel による分析の結果を基にして、この処理が行われます。
フェーズ、
統合されています一方、query
は、次の結果に対して実行されます。
オプションが評価される前の Bazel の読み込みフェーズ。
例:
$ cat > tree/BUILD <<EOF sh_library( name = "ash", deps = select({ ":excelsior": [":manna-ash"], ":americana": [":white-ash"], "//conditions:default": [":common-ash"], }), ) sh_library(name = "manna-ash") sh_library(name = "white-ash") sh_library(name = "common-ash") config_setting( name = "excelsior", values = {"define": "species=excelsior"}, ) config_setting( name = "americana", values = {"define": "species=americana"}, ) EOF
# Traditional query: query doesn't know which select() branch you will choose, # so it conservatively lists all of possible choices, including all used config_settings. $ bazel query "deps(//tree:ash)" --noimplicit_deps //tree:americana //tree:ash //tree:common-ash //tree:excelsior //tree:manna-ash //tree:white-ash # cquery: cquery lets you set build options at the command line and chooses # the exact dependencies that implies (and also the config_setting targets). $ bazel cquery "deps(//tree:ash)" --define species=excelsior --noimplicit_deps //tree:ash (9f87702) //tree:manna-ash (9f87702) //tree:americana (9f87702) //tree:excelsior (9f87702)
各結果には、次の一意の識別子 (9f87702)
が含まれます。
構成
使用されます。
cquery
は構成されたターゲット グラフに対して実行されるためです。インサイトがないということです
ビルド アクションや test_suite
へのアクセスなどのアーティファクトに統合できます。
構成されていないからです。前者については、aquery
をご覧ください。
基本的な構文
単純な cquery
呼び出しは次のようになります。
bazel cquery "function(//target)"
クエリ式 "function(//target)"
は、以下で構成されます。
function(...)
は、ターゲットで実行する関数です。cquery
ほとんどのquery
の関数の集合と、 いくつかあります。//target
は、関数にフィードされる式です。この例では、 単純なターゲットです。ただし、クエリ言語では関数のネストも可能です。 例については、クエリガイドをご覧ください。
cquery
には、読み込みと分析を行うターゲットが必要です。
学びました特に指定されていない限り、cquery
は、
クエリ式です。--universe_scope
を参照してください。
を使用して、トップレベルのビルド ターゲットの依存関係をクエリできます。
構成
次の行をご覧ください。
//tree:ash (9f87702)
は、//tree:ash
が ID 9f87702
の構成でビルドされていることを意味します。ほとんどの
これは、変数を定義するビルド オプション値の不透明なハッシュです。
できます。
構成の完全な内容を表示するには、次のコマンドを実行します。
$ bazel config 9f87702
9f87702
は、完全な ID の接頭辞です。これは、完全な ID が
SHA-256 ハッシュは長く、追跡が困難です。cquery
は、すべての有効な
プレフィックスを付加します。例:
Git ショート ハッシュ。
完全な ID を表示するには、$ bazel config
を実行します。
ターゲット パターンの評価
//foo
は、cquery
と query
で意味が異なります。その理由は、
cquery
は、構成されたターゲットを評価します。ビルドグラフには複数の
//foo
の構成済みバージョン。
cquery
の場合、クエリ式のターゲット パターンが評価されます。
そのパターンに一致するラベルが、構成済みのすべてのターゲットに適用されます。出力:
決定的だが、cquery
は
コアクエリ注文コントラクト。
これにより、query
よりもクエリ式でより繊細な結果が得られます。
たとえば、次の例では複数の結果が生成されます。
# Analyzes //foo in the target configuration, but also analyzes # //genrule_with_foo_as_tool which depends on an exec-configured # //foo. So there are two configured target instances of //foo in # the build graph. $ bazel cquery //foo --universe_scope=//foo,//genrule_with_foo_as_tool //foo (9f87702) //foo (exec)
クエリ対象のインスタンスを正確に宣言するには、次のコマンドを使用します。
config
関数
query
のターゲット パターンを表示
ドキュメントをご覧ください。
関数
一連の関数の
query
でサポートされますが、cquery
では次を除くすべてがサポートされています
allrdeps
、
buildfiles
,
rbuildfiles
,
siblings
,
tests
visible
cquery
には、次の新しい関数も導入されています。
config
expr ::= config(expr, word)
config
演算子は、構成されているターゲットを見つけようとします。
最初の引数で指定されるラベルと、
使用します。
2 番目の引数で有効な値は、null
または
カスタム設定ハッシュ。ハッシュは、$
bazel config
または以前の cquery
の出力から取得できます。
例:
$ bazel cquery "config(//bar, 3732cc8)" --universe_scope=//foo
$ bazel cquery "deps(//foo)" //bar (exec) //baz (exec) $ bazel cquery "config(//baz, 3732cc8)"
最初の引数のすべての結果が、指定された 見つかったもののみが返されます。結果がない場合 見つからない場合、クエリは失敗します。
オプション
ビルド オプション
cquery
は、通常の Bazel ビルドで実行されるため、次のセットを継承します。
ビルド中に使用可能なオプション。
Cquery オプションの使用
--universe_scope
(カンマ区切りリスト)
多くの場合、構成済みのターゲットの依存関係は 遷移 依存関係が互いに異なるものになります。このフラグ ターゲットが依存関係または推移的なターゲットとして作成されたかのように、ターゲットをクエリできる 依存関係が存在します。例:
# x/BUILD genrule( name = "my_gen", srcs = ["x.in"], outs = ["x.cc"], cmd = "$(locations :tool) $< >$@", tools = [":tool"], ) cc_binary( name = "tool", srcs = ["tool.cpp"], )
genrule のツールは exec 構成 したがって、次のクエリでは次のような出力が生成されます。
クエリ | ターゲット構築 | 出力 |
---|---|---|
bazel cquery "//x:tool" | //x:tool | //x:tool(targetconfig) |
bazel cquery "//x:tool"--universe_scope="//x:my_gen" | //x:my_gen | //x:tool(execconfig) |
このフラグを設定すると、その内容がビルドされます。未設定の場合、すべてのターゲット
クエリ式で記述されているとおりに作成されます。の推移的クロージャは、
構築ターゲットがクエリ全体として使用されます。いずれにしても
最上位でビルド可能であること(つまり、最上位レベルと互換性があること)
オプション)。cquery
は、これらを推移的に閉じて結果を返します。
使用しないでください。
一番上のクエリ式ですべてのターゲットを構築できる場合でも、
しない方がよい場合があります。たとえば、サービス アカウント キーを明示的に
--universe_scope
により、ターゲットのビルドが
構成を管理する必要がなくなります。使用する構成のどのバージョンを
(現在のところ、ターゲット タイプを
(完全に指定する必要はありません)。このフラグを設定する必要があります。
クエリ式が deps(//foo)
よりも複雑な場合。
--implicit_deps
(ブール値、デフォルト=True)
このフラグを false に設定すると、明示的に設定されていないすべての結果が除外されます。 BUILD ファイルに記述し、代わりに Bazel で他の場所に設定します。これには、解決済みのフィルタリングが含まれます 統合できます。
--tool_deps
(ブール値、デフォルト=True)
このフラグを false に設定すると、
そのパスは、ターゲットとターゲットの間の
構成と
ターゲット以外の構成。
クエリされたターゲットがターゲット構成にある場合、--notool_deps
を設定すると、
ターゲット構成に含まれているターゲットのみが返されます。クエリ対象の
ターゲットがターゲット以外の構成にある場合、--notool_deps
を設定すると、
ターゲット以外の構成でもターゲットを絞ることができます。通常、この設定はフィルタリングには影響しません。
解決されたツールチェーンが
含まれます
--include_aspects
(ブール値、デフォルト=True)
アスペクトによって追加された依存関係を含めます。
このフラグが無効になっている場合、cquery somepath(X, Y)
と
X がアスペクトを通じてのみ依存する場合、cquery deps(X) | grep 'Y'
は Y を省略します。
出力形式
デフォルトでは、cquery はラベルと構成のペアの依存関係順のリストを出力します。 結果を公開するためのその他のオプションは他にもあります。
切り替え効果
--transitions=lite --transitions=full
構成の遷移 さまざまなリソースの最上位レベルのターゲットの下に 構成ミスがないかチェックします。
たとえば、あるターゲットから、すべてのリソースに対して exec 構成への移行が
tools
属性で指定する必要があります。これらは属性と呼ばれ、
使用できます。ルールによって独自の構成に移行を課すこともできます。
いわゆるルールクラス遷移と呼ばれるものです。この出力形式では、
種類やビルドへの影響など
。
この出力形式は --transitions
フラグによってトリガーされます。このフラグはデフォルトで
NONE
に設定。FULL
モードまたは LITE
モードに設定できます。FULL
モードの出力
ルールクラスの遷移と属性の遷移に関する情報が表示されます。
移行前と移行後のオプションの詳しい差分を確認できます。LITE
モード
オプション diff なしで同じ情報が出力されます。
プロトコル メッセージ出力
--output=proto
このオプションを使用すると、生成されるターゲットがバイナリ プロトコルで出力されます。 あります。プロトコル バッファの定義については、 src/main/protobuf/analysis_v2.proto.
CqueryResult
は、cquery の結果を含むトップレベルのメッセージです。これは、
ConfiguredTarget
個のメッセージのリストと Configuration
個のリストがある
ブロックすることもできます。各 ConfiguredTarget
には、値が等しい configuration_id
があります。
対応する Configuration
メッセージの id
フィールドのものに置き換えます。
--[no]proto:include_configurations
デフォルトでは、クエリの結果は各クエリの一部として構成情報を返します。 表示されます。この情報を省略して proto 出力を取得する場合 出力する場合は、このフラグを false に設定します。
クエリの proto 出力のドキュメントを参照 をご覧ください。
出力をグラフ化する
--output=graph
このオプションは、Graphviz 互換の .dot ファイルとして出力を生成します。query
さんのチャンネルを見る
詳しくは、グラフ出力のドキュメントをご覧ください。cquery
は --graph:node_limit
と
--graph:factored
。
ファイル出力
--output=files
このオプションは、一致したターゲットごとに生成された出力ファイルのリストを出力します。
bazel build
の最後に出力されるリストと同様のクエリで照合します。
呼び出すことができます。出力には、リクエストされたファイルでアドバタイズされたファイルのみが含まれます。
出力グループが
--output_groups
フラグ。
これにはソースファイルが含まれます。
この出力形式によって出力されるすべてのパスは、
execroot:
bazel info execution_root
経由。bazel-out
コンビニエンス シンボリック リンクが存在する場合、
メイン リポジトリ内のファイルへのパスも、ワークスペースを基準として解決されます。
されます。
Starlark を使用した出力形式の定義
--output=starlark
この出力形式では、Starlark
関数がクエリの結果の構成済みターゲットごとに出力され、
返されます。--starlark:file
フラグは、Pod のロケーションを指定します。
単一のパラメータを持つ format
という名前の関数を定義する Starlark ファイル
target
。この関数は、
返されます。または、便宜上、
def format(target): return expr
として宣言された関数の本体を、
--starlark:expr
フラグ。
「cquery」Starlark 言語
cquery Starlark 環境は、BUILD ファイルまたは .bzl ファイルとは異なります。内容
すべてのコア Starlark
組み込みの定数と関数
に加えて、後述する cquery 固有のパラメータ(glob
などは除く)が含まれます。
native
、rule
などを使用できます。また、load ステートメントはサポートされていません。
build_options(target)
build_options(target)
は、キーがビルド オプション識別子であるマップを返します(
構成)
その値が Starlark 値です有効な値でない Starlark のビルド オプション
このマップでは省略されています
ターゲットが入力ファイルの場合、build_options(target)
は入力ファイルとして None を返します。
ターゲットに null 構成があります。
プロバイダ(ターゲット)
providers(target)
は、キーが名前であるマップを返します。
プロバイダ
(例: "DefaultInfo"
)で、その値が Starlark 値です。プロバイダ
値が正規でない Starlark 値はこのマップから省略されます。
例
//foo
によって生成されたすべてのファイルのベース名のスペース区切りリストを出力します。
bazel cquery //foo --output=starlark \ --starlark:expr="' '.join([f.basename for f in target.files.to_list()])"
rule ターゲットによって生成されたすべてのファイルのパスのスペース区切りリストを出力します。
//bar
とそのサブパッケージ:
bazel cquery 'kind(rule, //bar/...)' --output=starlark \ --starlark:expr="' '.join([f.path for f in target.files.to_list()])"
//foo
によって登録されたすべてのアクションのニーモニックのリストを出力します。
bazel cquery //foo --output=starlark \ --starlark:expr="[a.mnemonic for a in target.actions]"
cc_library
//baz
によって登録されたコンパイル出力のリストを出力します。
bazel cquery //baz --output=starlark \ --starlark:expr="[f.path for f in target.output_groups.compilation_outputs.to_list()]"
//foo
のビルド時にコマンドライン オプション --javacopt
の値を出力します。
bazel cquery //foo --output=starlark \ --starlark:expr="build_options(target)['//command_line_option:javacopt']"
各ターゲットのラベルを 1 つだけ出力します。この例では、 ファイルで定義されている Starlark 関数。
$ cat example.cquery def has_one_output(target): return len(target.files.to_list()) == 1 def format(target): if has_one_output(target): return target.label else: return "" $ bazel cquery //baz --output=starlark --starlark:file=example.cquery
厳密に Python 3 である各ターゲットのラベルを出力します。この例では、 ファイルで定義されている Starlark 関数。
$ cat example.cquery def format(target): p = providers(target) py_info = p.get("PyInfo") if py_info and py_info.has_py3_only_sources: return target.label else: return "" $ bazel cquery //baz --output=starlark --starlark:file=example.cquery
ユーザー定義のプロバイダから値を抽出します。
$ cat some_package/my_rule.bzl MyRuleInfo = provider(fields={"color": "the name of a color"}) def _my_rule_impl(ctx): ... return [MyRuleInfo(color="red")] my_rule = rule( implementation = _my_rule_impl, attrs = {...}, ) $ cat example.cquery def format(target): p = providers(target) my_rule_info = p.get("//some_package:my_rule.bzl%MyRuleInfo'") if my_rule_info: return my_rule_info.color return "" $ bazel cquery //baz --output=starlark --starlark:file=example.cquery
Cquery と query の比較
cquery
と query
は互いに補完し合い、
特定することです以下を参考に、どちらが適しているかを判断してください。
cquery
は特定のselect()
分岐をたどって、 作成したグラフをモデル化できます。query
はどれかわかりません そうすると、すべてのブランチを含めることで過大近似値になります。cquery
の精度のために、次の値よりも多くのグラフを構築する必要があります。query
では可能です。具体的には、cquery
構成されたターゲットを評価しますが、query
のみを評価します。 targets を評価します。これには時間とメモリの使用量が多くなります。cquery
による解釈 クエリ言語ではあいまいさが生じます 回避したいデータquery
たとえば"//foo"
が 2 つの構成に存在し、cquery "deps(//foo)"
で使用すべきですか?config
関数が役立ちます。cquery
は比較的新しいツールであるため、特定の用途はサポートされていません。 対応できます詳しくは、既知の問題をご覧ください。
既知の問題
cquery
が「ビルド」するすべてのターゲット同じ構成にする必要があります。
クエリを評価する前に、cquery
はビルドを
ビルド アクションが実行される前のステップです。ターゲットとなる
「ビルド」デフォルトでは、クエリに表示されるすべてのラベルから選択されます。
式(これはオーバーライドして
--universe_scope
に置き換えます)。これらの
同じ構成にする必要があります。
これらは通常、最上位の「ターゲット」を共有しますが構成、
構成を変更することもできます。
受信エッジ遷移。
ここで cquery
が不足しています。
回避策: 可能であれば、--universe_scope
をより厳格に設定します。
あります。例:
# This command attempts to build the transitive closures of both //foo and # //bar. //bar uses an incoming edge transition to change its --cpu flag. $ bazel cquery 'somepath(//foo, //bar)' ERROR: Error doing post analysis query: Top-level targets //foo and //bar have different configurations (top-level targets with different configurations is not supported) # This command only builds the transitive closure of //foo, under which # //bar should exist in the correct configuration. $ bazel cquery 'somepath(//foo, //bar)' --universe_scope=//foo
--output=xml
はサポートされていません。
非確定的な出力。
cquery
は、ビルドグラフを自動的にワイプしません。
過去のコマンドの結果を取得しやすくなるため、
分析できますたとえば、genquery
は exec 移行を実行します。
tools
属性です。つまり、
exec 構成。
この移行によって生じる影響については以下で確認できます。
$ cat > foo/BUILD <<<EOF genrule( name = "my_gen", srcs = ["x.in"], outs = ["x.cc"], cmd = "$(locations :tool) $< >$@", tools = [":tool"], ) cc_library( name = "tool", ) EOF $ bazel cquery "//foo:tool" tool(target_config) $ bazel cquery "deps(//foo:my_gen)" my_gen (target_config) tool (exec_config) ... $ bazel cquery "//foo:tool" tool(exec_config)
回避策: 起動オプションを変更して、構成されたターゲットの再分析を強制します。
たとえば、ビルドコマンドに --test_arg=<whatever>
を追加します。
トラブルシューティング
再帰ターゲット パターン(/...
)
問題が発生した場合:
$ bazel cquery --universe_scope=//foo:app "somepath(//foo:app, //foo/...)" ERROR: Error doing post analysis query: Evaluation failed: Unable to load package '[foo]' because package is not in scope. Check that all target patterns in query expression are within the --universe_scope of this query.
にもかかわらず、パッケージ //foo
が対象範囲外であることを誤って示唆しています。
--universe_scope=//foo:app
に含まれている。これは、インフラストラクチャの設計上の制約が原因で、
cquery
。回避策として、ユニバースに //foo/...
を明示的に含めます。
scope:
$ bazel cquery --universe_scope=//foo:app,//foo/... "somepath(//foo:app, //foo/...)"
それでも問題が解決しない場合(たとえば、//foo/...
の一部のターゲットが
(選択したビルドフラグを使用してビルドする)と、手動で
構成要素パッケージを前処理するクエリによって構成します。
# Replace "//foo/..." with a subshell query call (not cquery!) outputting each package, piped into # a sed call converting "<pkg>" to "//<pkg>:*", piped into a "+"-delimited line merge. # Output looks like "//foo:*+//foo/bar:*+//foo/baz". # $ bazel cquery --universe_scope=//foo:app "somepath(//foo:app, $(bazel query //foo/... --output=package | sed -e 's/^/\/\//' -e 's/$/:*/' | paste -sd "+" -))"