Aquery (Action Graph Query)
Overview
Caution: The aquery command is still experimental and its API will change.
The aquery
command allows you to query for actions in your build graph.
It operates on the post-analysis Configured Target Graph and exposes
information about Actions, Artifacts and their relationships.
aquery
is useful when we are interested in the properties of the Actions/Artifacts
generated from the Configured Target Graph. For example, the actual commands run
and their inputs/outputs/mnemonics.
The tool accepts several command-line options. Notably, the aquery command runs on top of a regular Bazel build and inherits the set of options available during a build.
It supports the same set of functions that is also available to traditional
query
but siblings
, buildfiles
and
tests
.
An example aquery
output (without specific details):
$ bazel aquery 'deps(//some:label)' action 'Writing file some_file_name' Mnemonic: ... Owner: ... Configuration: ... ActionKey: ... Inputs: [...] Outputs: [...]
Basic Syntax
A simple example of the syntax for aquery
is as follows:
bazel aquery "aquery_function(function(//target))"
The query expression (in quotes) consists of the following:
-
aquery_function(...)
: functions specific toaquery
. More details below. -
function(...)
: the standard functions as traditionalquery
. -
//target
is the label to the interested target.
# aquery examples: # Get the action graph generated while building //src/target_a $ bazel aquery '//src/target_a' # Get the action graph generated while building all dependencies of //src/target_a $ bazel aquery 'deps(//src/target_a)' # Get the action graph generated while building all dependencies of //src/target_a # whose inputs filenames match the regex ".*cpp". $ bazel aquery 'inputs(".*cpp, deps(//src/target_a))'
Aquery Functions
There are currently 3 aquery
functions:
inputs
: filter actions by inputs.outputs
: filter actions by outputsmnemonic
: filter actions by mnemonic
expr ::= inputs(word, expr)
The inputs
operator returns the actions generated from building expr
,
whose input filenames match the regex provided by word
.
$ bazel aquery 'inputs(".*cpp", deps(//src/target_a))'
outputs
and mnemonic
functions share a similar syntax.
You can also combine functions to achieve the AND operation. For example:
$ bazel aquery 'mnemonic("Cpp.*", (inputs(".*cpp", inputs("foo.*", //src/target_a))))'
The above command would find all actions involved in building //src/target_a
,
whose mnemonics match "Cpp.*"
and inputs match the patterns
".*cpp"
and "foo.*"
.
Important: aquery functions can't be nested inside non-aquery functions
- Conceptually this makes sense since the output of aquery functions is Actions, not Configured Targets.
-
An example of the syntax error produced:
$ bazel aquery 'deps(inputs(".*cpp", //src/target_a))' ERROR: aquery filter functions (inputs, outputs, mnemonic) produce actions, and therefore can't be the input of other function types: deps deps(inputs(".*cpp", //src/target_a))
Options
Build Options
aquery
runs on top of a regular Bazel build and thus inherits the set of
options
available during a build.
Aquery options
--output=(text|proto|textproto), default=text
The default output format (text
) is human-readable,
use proto
or textproto
for machine-readable format.
--include_commandline, default=true
Includes the content of the action command lines in the output (potentially large).
--include_aspects, default=false
Whether to include Aspect-generated actions in the output.
--include_param_files, default=false
Include the content of the param files used in the command (potentially large).
Warning: Enabling this flag will automatically enable the --include_commandline
flag.
Miscellaneous
Aspect-on-Aspect
It is possible for Aspects to be applied on top of each other. The aquery output of the action generated by these Aspects would then include the Aspect path, which is the sequence of Aspects applied to the target which generated the action.
An example of Aspect-on-Aspect:
t0 ^ | <- a1 t1 ^ | <- a2 t2
Let ti be a target of rule ri, which applies an Aspect ai to its dependencies.
Assume that a2 generates an action X when applied to target t0. The text output of
bazel aquery --include_aspects 'deps(//t2)'
for action X would be:
action ... Mnemonic: ... Target: //my_pkg:t0 Configuration: ... AspectDescriptors: [//my_pkg:rule.bzl%a2(foo=...) -> //my_pkg:rule.bzl%a1(bar=...)] ...
This means that action X
was generated by Aspect a2
applied onto
a1(t0)
, where a1(t0)
is the result of Aspect a1
applied
onto target t0
.
Each AspectDescriptor
has the following format:
AspectClass([param=value,...])
AspectClass
could be the name of the Aspect class (for native Aspects) or
bzl_file%aspect_name
(for Starlark Aspects). AspectDescriptor
are
sorted in topological order of the
dependency graph.
Known Issues
The list of aquery issues/planned features can be found on GitHub.
Updates
Aquery is a work in progress, and its API might change in the future. Please contact twerth@google.com and leba@google.com for any issue/feature request.