--- layout: documentation title: Query how-to ---
This is a quick tutorial to get you started using Bazel's query language to trace dependencies in your code.
For a language details and --output
flag details, please see the reference manual, Bazel query reference. You can get help for Bazel query by typing bazel help query
.
To execute a query while ignoring errors such as missing targets, use the --keep_going flag.
foo
?
foo
package?
foo
package?
//foo
?
test_suite
expands to?
foo
that match a pattern?
src/main/java/com/example/cache/LRUCache.java
?
src/main/java/com/example/cache/LRUCache.java
?
src/main/java/com/example/cache/LRUCache.java
as a source?
//src/main/java/com/example/base:base
, use the deps
function in bazel query:
$ bazel query "deps(src/main/java/com/example/base:base)" //resources:translation.xml //src/main/java/com/example/base:AbstractPublishedUri.java ...This is the set of all targets required to build
//src/main/java/com/example/base:base
.
//third_party/zlib:zlibonly
isn't in the BUILD file for //src/main/java/com/example/base
, but it is an indirect dependency. How can we trace this dependency path? There are two useful functions here: allpaths
and somepath
$ bazel query "somepath(src/main/java/com/example/base:base, third_party/zlib:zlibonly)" //src/main/java/com/example/base:base //translations/tools:translator //translations/base:base //third_party/py/MySQL:MySQL //third_party/py/MySQL:_MySQL.so //third_party/mysql:mysql //third_party/zlib:zlibonly $ bazel query "allpaths(src/main/java/com/example/common/base:base, third_party/...)" ...many errors detected in BUILD files... //src/main/java/com/example/common/base:base //third_party/java/jsr166x:jsr166x //third_party/java/sun_servlet:sun_servlet //src/main/java/com/example/common/flags:flags //src/main/java/com/example/common/flags:base //translations/tools:translator //translations/tools:aggregator //translations/base:base //tools/pkg:pex //tools/pkg:pex_phase_one //tools/pkg:pex_lib //third_party/python:python_lib //translations/tools:messages //third_party/py/xml:xml //third_party/py/xml:utils/boolean.so //third_party/py/xml:parsers/sgmlop.so //third_party/py/xml:parsers/pyexpat.so //third_party/py/MySQL:MySQL //third_party/py/MySQL:_MySQL.so //third_party/mysql:mysql //third_party/openssl:openssl //third_party/zlib:zlibonly //third_party/zlib:zlibonly_v1_2_3 //third_party/python:headers //third_party/openssl:crypto
src/main/java/com/example/common/base
never references //translations/tools:aggregator
. So, where's the direct dependency?
Certain rules include implicit dependencies on additional libraries or tools. For example, to build a genproto
rule, you need first to build the Protocol Compiler, so every genproto
rule carries an implicit dependency on the protocol compiler. These dependencies are not mentioned in the build file, but added in by the build tool. The full set of implicit dependencies is currently undocumented; read the source code of RuleClassProvider.)
rdeps(u, x)
to find the reverse dependencies of the targets in x
within the transitive closure of u
.
Unfortunately, invoking, e.g.,
rdeps(..., daffie/annotations2:constants-lib)
is not practical for a large tree, because it requires parsing every BUILD file and building a very large dependency graph (Bazel may run out of memory). If you would like to execute this query across a large repository, you may have to query subtrees and then combine the results.
bazel query
to analyze many dependency relationships.
foo
? bazel query 'foo/...' --output package
foo
package? bazel query 'kind(rule, foo:all)' --output label_kind
foo
package? bazel query 'kind("generated file", //foo:*)'
//foo
? bazel query 'buildfiles(deps(//foo))' --output location | cut -f1 -d:
test_suite
expands to? bazel query 'tests(//foo:smoke_tests)'
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
bazel query 'attr(size, small, tests(//foo:smoke_tests))'
bazel query 'attr(size, medium, tests(//foo:smoke_tests))'
bazel query 'attr(size, large, tests(//foo:smoke_tests))'
foo
that match a pattern? bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'
The pattern is a regex and is applied to the full name of the rule. It's similar to doing
bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'
src/main/java/com/example/cache/LRUCache.java
? bazel query 'buildfiles(src/main/java/com/example/cache/LRUCache.java)' --output=package
src/main/java/com/example/cache/LRUCache.java
? bazel query src/main/java/com/example/cache/LRUCache.java
src/main/java/com/example/cache/LRUCache.java
as a source? fullname=$(bazel query src/main/java/com/example/cache/LRUCache.java) bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"
foo
depend on? (What do I need to check out to build foo
) bazel query 'buildfiles(deps(//foo:foo))' --output package
Note, buildfiles
is required in order to correctly obtain all files
referenced by subinclude
; see the reference manual for details.
foo
tree depend on, excluding foo/contrib
? bazel query 'deps(foo/... except foo/contrib/...)' --output package
bazel query 'kind(genproto, deps(bar/...))'
bazel query 'some(kind(cc_.*library, deps(kind(java_binary, src/main/java/com/example/frontend/...))))' --output location
bazel query 'let jbs = kind(java_binary, src/main/java/com/example/frontend/...) in let cls = kind(cc_.*library, deps($jbs)) in $jbs intersect allpaths($jbs, $cls)'
bazel query 'kind("source file", deps(src/main/java/com/example/qux/...))' | grep java$
Generated files: bazel query 'kind("generated file", deps(src/main/java/com/example/qux/...))' | grep java$
bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
Generated files: bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$
//foo
depend on that //foo:foolib
does not? bazel query 'deps(//foo) except deps(//foo:foolib)'
foo
tests depend on that the //foo
production binary does not depend on? bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'
bar
depend on groups2
? bazel query 'somepath(bar/...,groups2/...:*)'
Once you have the results of this query, you will often find that a
single target stands out as being an unexpected or egregious and
undesirable dependency of bar
. The query can then
be further refined to:
docker/updater:updater_systest
(a py_test
) to some cc_library
that it depends upon: bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in somepath(docker/updater:updater_systest, $cc)'
//photos/frontend:lib
depend on two variants of the same library //third_party/jpeglib
and //third_party/jpeg
? //photos/frontend:lib
that depends on both libraries". When shown
in topological order, the last element of the result is the most
likely culprit.
% bazel query 'allpaths(//photos/frontend:lib, //third_party/jpeglib) intersect allpaths(//photos/frontend:lib, //third_party/jpeg)' //photos/frontend:lib //photos/frontend:lib_impl //photos/frontend:lib_dispatcher //photos/frontend:icons //photos/frontend/modules/gadgets:gadget_icon //photos/thumbnailer:thumbnail_lib //third_party/jpeg/img:renderer
bazel query 'bar/... intersect allpaths(bar/..., Y)'
Note: X intersect allpaths(X, Y)
is the general idiom for the query "which X depend on Y?"
If expression X is non-trivial, it may be convenient to bind a name to it using
let
to avoid duplication.
bar
no longer depend on X? png
file:
bazel query 'allpaths(bar/...,X)' --output graph | dot -Tpng > /tmp/dep.png
ServletSmokeTests
build? maxrank
:
% bazel query 'deps(//src/test/java/com/example/servlet:ServletSmokeTests)' --output maxrank | tail -1 85 //third_party/zlib:zutil.cThe result indicates that there exist paths of length 85 that must occur in order in this build.