cquery is a variant of query that correctly handles
select() and build options’ effects on the
build graph.
It achieves this by running over the results of Bazel’s analysis
phase,
which integrates these effects. query, by contrast, runs over the results of
Bazel’s loading phase, before options are evaluated.
For example:
(9f87702) of
the configuration the
target is built with.
Since cquery runs over the configured target graph. it doesn’t have insight
into artifacts like build actions nor access to test_suite
rules as they are not configured targets. For the former, see aquery.
Basic syntax
A simplecquery call looks like:
bazel cquery "function(//target)"
The query expression "function(//target)" consists of the following:
function(...)is the function to run on the target.cquerysupports most ofquery’s functions, plus a few new ones.//targetis the expression fed to the function. In this example, the expression is a simple target. But the query language also allows nesting of functions. See the Query guide for examples.
cquery requires a target to run through the loading and analysis
phases. Unless otherwise specified, cquery parses the target(s) listed in the
query expression. See --universe_scope
for querying dependencies of top-level build targets.
Configurations
The line://tree:ash was built in a configuration with ID 9f87702. For most
targets, this is an opaque hash of the build option values defining the
configuration.
To see the configuration’s complete contents, run:
9f87702 is a prefix of the complete ID. This is because complete IDs are
SHA-256 hashes, which are long and hard to follow. cquery understands any valid
prefix of a complete ID, similar to
Git short hashes.
To see complete IDs, run $ bazel config.
Target pattern evaluation
//foo has a different meaning for cquery than for query. This is because
cquery evaluates configured targets and the build graph may have multiple
configured versions of //foo.
For cquery, a target pattern in the query expression evaluates
to every configured target with a label that matches that pattern. Output is
deterministic, but cquery makes no ordering guarantee beyond the
core query ordering contract.
This produces subtler results for query expressions than with query.
For example, the following can produce multiple results:
config function.
See query’s target pattern
documentation for more information on target
patterns.
Functions
Of the set of functions supported byquery, cquery supports all but
allrdeps,
buildfiles,
rbuildfiles,
siblings, tests, and
visible.
cquery also introduces the following new functions:
config
expr ::= config(expr, word)
The config operator attempts to find the configured target for
the label denoted by the first argument and configuration specified by the
second argument.
Valid values for the second argument are null or a
custom configuration hash. Hashes can be retrieved from $ bazel config or a previous cquery’s output.
Examples:
Options
Build options
cquery runs over a regular Bazel build and thus inherits the set of
options available during a
build.
Using cquery options
--universe_scope (comma-separated list)
Often, the dependencies of configured targets go through
transitions,
which causes their configuration to differ from their dependent. This flag
allows you to query a target as if it were built as a dependency or a transitive
dependency of another target. For example:
| Query | Target Built | Output |
|---|---|---|
| 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 returns results in the transitive closure of these
top-level targets.
Even if it’s possible to build all targets in a query expression at the top
level, it may be beneficial to not do so. For example, explicitly setting
--universe_scope could prevent building targets multiple times in
configurations you don’t care about. It could also help specify which
configuration version of a target you’re looking for. You should set this flag
if your query expression is more complex than deps(//foo).
--implicit_deps (boolean, default=True)
Setting this flag to false filters out all results that aren’t explicitly set in
the BUILD file and instead set elsewhere by Bazel. This includes filtering
resolved toolchains.
--tool_deps (boolean, default=True)
Setting this flag to false filters out all configured targets for which the
path from the queried target to them crosses a transition between the target
configuration and the
non-target configurations. If the queried
target is in the target configuration, setting --notool_deps will only return
targets that also are in the target configuration. If the queried target is in a
non-target configuration, setting --notool_deps will only return targets also
in non-target configurations. This setting generally does not affect filtering
of resolved toolchains.
--include_aspects (boolean, default=True)
Include dependencies added by aspects.
If this flag is disabled, cquery somepath(X, Y) and
cquery deps(X) | grep 'Y' omit Y if X only depends on it through an aspect.
Output formats
By default, cquery outputs results in a dependency-ordered list of label and configuration pairs. There are other options for exposing the results as well.Transitions
tools attribute. These are known as attribute
transitions. Rules can also impose transitions on their own configurations,
known as rule class transitions. This output format outputs information about
these transitions such as what type they are and the effect they have on build
options.
This output format is triggered by the --transitions flag which by default is
set to NONE. It can be set to FULL or LITE mode. FULL mode outputs
information about rule class transitions and attribute transitions including a
detailed diff of the options before and after the transition. LITE mode
outputs the same information without the options diff.
Protocol message output
CqueryResult is the top level message containing the results of the cquery. It
has a list of ConfiguredTarget messages and a list of Configuration
messages. Each ConfiguredTarget has a configuration_id whose value is equal
to that of the id field from the corresponding Configuration message.
—[no]proto:include_configurations
By default, cquery results return configuration information as part of each configured target. If you’d like to omit this information and get proto output that is formatted exactly like query’s proto output, set this flag to false. See query’s proto output documentation for more proto output-related options. Note: While selects are resolved both at the top level of returned targets and within attributes, all possible inputs for selects are still included asrule_input fields.
Graph output
query’s
graph output documentation for details. cquery
also supports --graph:node_limit and
--graph:factored.
Files output
bazel build
invocation. The output contains only the files advertised in the requested
output groups as determined by the
--output_groups flag.
It does include source files.
All paths emitted by this output format are relative to the
execroot, which can be obtained
via bazel info execution_root. If the bazel-out convenience symlink exists,
paths to files in the main repository also resolve relative to the workspace
directory.
Note: The output of bazel cquery --output=files //pkg:foo contains the output
files of //pkg:foo in all configurations that occur in the build (also see
the section on target pattern evaluation). If that
is not desired, wrap you query in config(..., target).
Defining the output format using Starlark
--starlark:file flag specifies the location of a
Starlark file that defines a function named format with a single parameter,
target. This function is called for each Target
in the query result. Alternatively, for convenience, you may specify just the
body of a function declared as def format(target): return expr by using the
--starlark:expr flag.
‘cquery’ Starlark dialect
The cquery Starlark environment differs from a BUILD or .bzl file. It includes all core Starlark built-in constants and functions, plus a few cquery-specific ones described below, but not (for example)glob,
native, or rule, and it does not support load statements.
build_options(target)
build_options(target) returns a map whose keys are build option identifiers
(see Configurations) and whose values are their Starlark
values. Build options whose values are not legal Starlark values are omitted
from this map.
If the target is an input file, build_options(target) returns None, as input
file targets have a null configuration.
providers(target)
providers(target) returns a map whose keys are names of
providers
(for example, "DefaultInfo") and whose values are their Starlark values.
Providers whose values are not legal Starlark values are omitted from this map.
Examples
Print a space-separated list of the base names of all files produced by//foo:
//bar and its subpackages:
//foo.
cc_library //baz.
--javacopt when building //foo.
cquery vs. query
cquery and query complement each other and excel in
different niches. Consider the following to decide which is right for you:
cqueryfollows specificselect()branches to model the exact graph you build.querydoesn’t know which branch the build chooses, so overapproximates by including all branches.cquery’s precision requires building more of the graph thanquerydoes. Specifically,cqueryevaluates configured targets whilequeryonly evaluates targets. This takes more time and uses more memory.cquery’s interpretation of the query language introduces ambiguity thatqueryavoids. For example, if"//foo"exists in two configurations, which one shouldcquery "deps(//foo)"use? Theconfigfunction can help with this.
Non-deterministic output
cquery does not automatically wipe the build graph from previous commands.
It’s therefore prone to picking up results from past queries.
For example, genrule exerts an exec transition on its tools attribute -
that is, it configures its tools in the [exec configuration]
(https://bazel.build/rules/rules#configurations).
You can see the lingering effects of that transition below.
blaze clean before your cquery to ensure a fresh
analysis graph.
Troubleshooting
Recursive target patterns (/...)
If you encounter:
//foo isn’t in scope even though
--universe_scope=//foo:app includes it. This is due to design limitations in
cquery. As a workaround, explicitly include //foo/... in the universe
scope:
//foo/... can’t
build with the chosen build flags), manually unwrap the pattern into its
constituent packages with a pre-processing query: