| Project: /_project.yaml |
| Book: /_book.yaml |
| |
| # 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](/reference/query) |
| and [Bazel cquery reference](/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](/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. |