| --- | |
| title: 'Bazel Query How-To' | |
| --- | |
| This page covers how to get started using Bazel's query language to trace | |
| dependencies in your code. | |
| For a language details and `--output` flag details, please see the | |
| reference manuals, [Bazel query reference](/versions/6.4.0/reference/query) | |
| and [Bazel cquery reference](/versions/6.4.0/docs/cquery). You can get help by | |
| typing `bazel help query` or `bazel help cquery` on the | |
| command line. | |
| To execute a query while ignoring errors such as missing targets, use the | |
| `--keep_going` flag. | |
| ## Finding the dependencies of a rule {:#finding-rule-dependencies} | |
| To see the dependencies of `//foo`, use the | |
| `deps` function in bazel query: | |
| <pre> | |
| $ bazel query "deps(//foo)" | |
| //foo:foo | |
| //foo:foo-dep | |
| ... | |
| </pre> | |
| This is the set of all targets required to build `//foo`. | |
| ## Tracing the dependency chain between two packages {:#tracing-dependency-chain} | |
| The library `//third_party/zlib:zlibonly` isn't in the BUILD file for | |
| `//foo`, but it is an indirect dependency. How can | |
| we trace this dependency path? There are two useful functions here: | |
| `allpaths` and `somepath`. You may also want to exclude | |
| tooling dependencies with `--notool_deps` if you care only about | |
| what is included in the artifact you built, and not every possible job. | |
| To visualize the graph of all dependencies, pipe the bazel query output through | |
| the `dot` command-line tool: | |
| <pre> | |
| $ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg | |
| </pre> | |
| Note: `dot` supports other image formats, just replace `svg` with the | |
| format identifier, for example, `png`. | |
| When a dependency graph is big and complicated, it can be helpful start with a single path: | |
| <pre> | |
| $ bazel query "somepath(//foo:foo, third_party/zlib:zlibonly)" | |
| //foo:foo | |
| //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 | |
| </pre> | |
| If you do not specify `--output graph` with `allpaths`, | |
| you will get a flattened list of the dependency graph. | |
| <pre> | |
| $ bazel query "allpaths(//foo, third_party/...)" | |
| ...many errors detected in BUILD files... | |
| //foo:foo | |
| //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 | |
| </pre> | |
| ### Aside: implicit dependencies {:#implicit-dependencies} | |
| The BUILD file for `//foo` 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. Using `--noimplicit_deps` allows you to filter out | |
| these deps from your query results. For cquery, this will include resolved toolchains. | |
| ## Reverse dependencies {:#reverse-dependencies} | |
| You might want to know the set of targets that depends on some target. For instance, | |
| if you're going to change some code, you might want to know what other code | |
| you're about to break. You can use `rdeps(u, x)` to find the reverse | |
| dependencies of the targets in `x` within the transitive closure of `u`. | |
| Bazel's [Sky Query](/versions/6.4.0/reference/query#sky-query) | |
| supports the `allrdeps` function which allows you to query reverse dependencies | |
| in a universe you specify. | |
| ## Miscellaneous uses {:#miscellaneous-uses} | |
| You can use `bazel query` to analyze many dependency relationships. | |
| ### What exists ... {:#what-exists} | |
| #### What packages exist beneath `foo`? {:#what-exists-beneath-foo} | |
| <pre>bazel query 'foo/...' --output package</pre> | |
| #### What rules are defined in the `foo` package? {:#rules-defined-in-foo} | |
| <pre>bazel query 'kind(rule, foo:*)' --output label_kind</pre> | |
| #### What files are generated by rules in the `foo` package? {:#files-generated-by-rules} | |
| <pre>bazel query 'kind("generated file", //foo:*)'</pre> | |
| #### What targets are generated by starlark macro `foo`? {:#targets-generated-by-foo} | |
| <pre>bazel query 'attr(generator_function, foo, //path/to/search/...)'</pre> | |
| #### What's the set of BUILD files needed to build `//foo`? {:#build-files-required} | |
| <pre>bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:</pre> | |
| #### What are the individual tests that a `test_suite` expands to? {:#individual-tests-in-testsuite} | |
| <pre>bazel query 'tests(//foo:smoke_tests)'</pre> | |
| #### Which of those are C++ tests? {:#cxx-tests} | |
| <pre>bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'</pre> | |
| #### Which of those are small? Medium? Large? {:#size-of-tests} | |
| <pre> | |
| 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))' | |
| </pre> | |
| #### What are the tests beneath `foo` that match a pattern? {:#tests-beneath-foo} | |
| <pre>bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'</pre> | |
| The pattern is a regex and is applied to the full name of the rule. It's similar to doing | |
| <pre>bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'</pre> | |
| #### What package contains file `path/to/file/bar.java`? {:#barjava-package} | |
| <pre> bazel query path/to/file/bar.java --output=package</pre> | |
| #### What is the build label for `path/to/file/bar.java?` {:#barjava-build-label} | |
| <pre>bazel query path/to/file/bar.java</pre> | |
| #### What rule target(s) contain file `path/to/file/bar.java` as a source? {:#barjava-rule-targets} | |
| <pre> | |
| fullname=$(bazel query path/to/file/bar.java) | |
| bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)" | |
| </pre> | |
| ### What package dependencies exist ... {:#package-dependencies} | |
| #### What packages does `foo` depend on? (What do I need to check out to build `foo`) {:#packages-foo-depends-on} | |
| <pre>bazel query 'buildfiles(deps(//foo:foo))' --output package</pre> | |
| Note: `buildfiles` is required in order to correctly obtain all files | |
| referenced by `subinclude`; see the reference manual for details. | |
| #### What packages does the `foo` tree depend on, excluding `foo/contrib`? {:#packages-foo-tree-depends-on} | |
| <pre>bazel query 'deps(foo/... except foo/contrib/...)' --output package</pre> | |
| ### What rule dependencies exist ... {:#rule-dependencies} | |
| #### What genproto rules does bar depend upon? {:#genproto-rules} | |
| <pre>bazel query 'kind(genproto, deps(bar/...))'</pre> | |
| #### Find the definition of some JNI (C++) library that is transitively depended upon by a Java binary rule in the servlet tree. {:#jni-library} | |
| <pre>bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location</pre> | |
| ##### ...Now find the definitions of all the Java binaries that depend on them {:#java-binaries} | |
| <pre>bazel query 'let jbs = kind(java_binary, //java/com/example/frontend/...) in | |
| let cls = kind(cc_.*library, deps($jbs)) in | |
| $jbs intersect allpaths($jbs, $cls)' | |
| </pre> | |
| ### What file dependencies exist ... {:#file-dependencies} | |
| #### What's the complete set of Java source files required to build foo? {:#java-source-files} | |
| Source files: | |
| <pre>bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$</pre> | |
| Generated files: | |
| <pre>bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$</pre> | |
| #### What is the complete set of Java source files required to build QUX's tests? {:qux-tests} | |
| Source files: | |
| <pre>bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$</pre> | |
| Generated files: | |
| <pre>bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$</pre> | |
| ### What differences in dependencies between X and Y exist ... {:#differences-in-dependencies} | |
| #### What targets does `//foo` depend on that `//foo:foolib` does not? {:#foo-targets} | |
| <pre>bazel query 'deps(//foo) except deps(//foo:foolib)'</pre> | |
| #### What C++ libraries do the `foo` tests depend on that the `//foo` production binary does _not_ depend on? {:#foo-cxx-libraries} | |
| <pre>bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'</pre> | |
| ### Why does this dependency exist ... {:#why-dependencies} | |
| #### Why does `bar` depend on `groups2`? {:#dependency-bar-groups2} | |
| <pre>bazel query 'somepath(bar/...,groups2/...:*)'</pre> | |
| 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: | |
| #### Show me a path from `docker/updater:updater_systest` (a `py_test`) to some `cc_library` that it depends upon: {:#path-docker-cclibrary} | |
| <pre>bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in | |
| somepath(docker/updater:updater_systest, $cc)'</pre> | |
| #### Why does library `//photos/frontend:lib` depend on two variants of the same library `//third_party/jpeglib` and `//third_party/jpeg`? {:#library-two-variants} | |
| This query boils down to: "show me the subgraph of `//photos/frontend:lib` that | |
| depends on both libraries". When shown in topological order, the last element | |
| of the result is the most likely culprit. | |
| <pre>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 | |
| </pre> | |
| ### What depends on ... {:#depends-on} | |
| #### What rules under bar depend on Y? {:#rules-bar-y} | |
| <pre>bazel query 'bar/... intersect allpaths(bar/..., Y)'</pre> | |
| 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. | |
| #### What targets directly depend on T, in T's package? {:#targets-t} | |
| <pre>bazel query 'same_pkg_direct_rdeps(T)'</pre> | |
| ### How do I break a dependency ... {:#break-dependency} | |
| <!-- TODO find a convincing value of X to plug in here --> | |
| #### What dependency paths do I have to break to make `bar` no longer depend on X? {:#break-dependency-bar-x} | |
| To output the graph to a `svg` file: | |
| <pre>bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg</pre> | |
| ### Misc {:#misc} | |
| #### How many sequential steps are there in the `//foo-tests` build? {:#steps-footests} | |
| Unfortunately, the query language can't currently give you the longest path | |
| from x to y, but it can find the (or rather _a_) most distant node from the | |
| starting point, or show you the _lengths_ of the longest path from x to every | |
| y that it depends on. Use `maxrank`: | |
| <pre>bazel query 'deps(//foo-tests)' --output maxrank | tail -1 | |
| 85 //third_party/zlib:zutil.c</pre> | |
| The result indicates that there exist paths of length 85 that must occur in | |
| order in this build. |