Guía de consultas

Informar un problema Ver fuente

En esta página, se explica cómo comenzar a usar el lenguaje de consulta de Bazel para hacer un seguimiento de las dependencias en tu código.

Para obtener detalles de los lenguajes y las marcas --output, consulta los manuales de referencia, la referencia de consultas de Bazel y la referencia de cquery de Bazel. Para obtener ayuda, escribe bazel help query o bazel help cquery en la línea de comandos.

Para ejecutar una consulta mientras ignoras los errores, como los destinos faltantes, usa la marca --keep_going.

Busca las dependencias de una regla

Para ver las dependencias de //foo, usa la función deps en la consulta de Bazel:

$ bazel query "deps(//foo)"
//foo:foo
//foo:foo-dep
...

Este es el conjunto de todos los destinos necesarios para compilar //foo.

Hacer un seguimiento de la cadena de dependencias entre dos paquetes

La biblioteca //third_party/zlib:zlibonly no está en el archivo BUILD para //foo, pero es una dependencia indirecta. ¿Cómo podemos hacer un seguimiento de esta ruta de dependencia? Existen dos funciones útiles aquí: allpaths y somepath. Es posible que también desees excluir dependencias de herramientas con --notool_deps si solo te importa lo que incluye el artefacto que compilaste y no todos los trabajos posibles.

Para visualizar el gráfico de todas las dependencias, canaliza el resultado de la consulta de Bazel a través de la herramienta de línea de comandos de dot:

$ bazel query "allpaths(//foo, third_party/...)" --notool_deps --output graph | dot -Tsvg > /tmp/deps.svg

Cuando un gráfico de dependencias es grande y complicado, puede ser útil comenzar con una sola ruta:

$ 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

Si no especificas --output graph con allpaths, obtendrás una lista plana del gráfico de dependencia.

$ 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

Apartado: dependencias implícitas

El archivo BUILD para //foo nunca hace referencia a //translations/tools:aggregator. Entonces, ¿dónde está la dependencia directa?

Ciertas reglas incluyen dependencias implícitas en bibliotecas o herramientas adicionales. Por ejemplo, para compilar una regla genproto, primero debes compilar el compilador de protocolos, por lo que cada regla genproto lleva una dependencia implícita del compilador de protocolos. Estas dependencias no se mencionan en el archivo de compilación, sino que la herramienta de compilación las agrega. Actualmente, el conjunto completo de dependencias implícitas no está documentado. Usar --noimplicit_deps te permite filtrar estas dependencias de los resultados de tu consulta. Para cquery, se incluirán cadenas de herramientas resueltas.

Cómo revertir dependencias

Es posible que desees conocer el conjunto de objetivos que depende de algún objetivo. Por ejemplo, si vas a cambiar algún código, es posible que desees saber qué otro código estás a punto de romper. Puedes usar rdeps(u, x) para encontrar las dependencias inversas de los objetivos en x dentro del cierre transitivo de u.

Sky Query de Bazel admite la función allrdeps, que te permite consultar dependencias inversas en un universo que especifiques.

Otros usos

Puedes usar bazel query para analizar muchas relaciones de dependencia.

Lo que existe ...

¿Qué paquetes existen debajo de foo?

bazel query 'foo/...' --output package

¿Qué reglas se definen en el paquete foo?

bazel query 'kind(rule, foo:*)' --output label_kind

¿Qué archivos se generan según las reglas del paquete foo?

bazel query 'kind("generated file", //foo:*)'

¿Qué objetivos genera la macro de Starlark foo?

bazel query 'attr(generator_function, foo, //path/to/search/...)'

¿Cuál es el conjunto de archivos BUILD necesarios para compilar //foo?

bazel query 'buildfiles(deps(//foo))' | cut -f1 -d:

¿Cuáles son las pruebas individuales a las que se expande un elemento test_suite?

bazel query 'tests(//foo:smoke_tests)'

¿Cuáles de estas opciones son pruebas C++?

bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'

¿Cuáles de esas opciones son pequeñas? ¿Media? ¿Grande?

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))'

¿Cuáles son las pruebas en foo que coinciden con un patrón?

bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'

El patrón es una regex y se aplica al nombre completo de la regla. Es similar a hacer

bazel query 'kind(".*_test rule", //foo/...)' | grep -E 'pa?t'

¿Qué paquete contiene el archivo path/to/file/bar.java?

 bazel query path/to/file/bar.java --output=package

¿Cuál es la etiqueta de compilación de path/to/file/bar.java??

bazel query path/to/file/bar.java

¿Qué destinos de la regla contienen el archivo path/to/file/bar.java como fuente?

fullname=$(bazel query path/to/file/bar.java)
bazel query "attr('srcs', $fullname, ${fullname//:*/}:*)"

Qué dependencias de paquete existen ...

¿De qué paquetes depende foo? (¿Qué necesito verificar para crear foo?

bazel query 'buildfiles(deps(//foo:foo))' --output package

¿De qué paquetes depende el árbol foo, excepto foo/contrib?

bazel query 'deps(foo/... except foo/contrib/...)' --output package

Qué dependencias de reglas existen ...

¿De qué reglas genproto depende de la barra?

bazel query 'kind(genproto, deps(bar/...))'

Encuentra la definición de alguna biblioteca JNI (C++) de la que depende de forma transitiva una regla binaria de Java en el árbol de servlets.

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Ahora encuentra las definiciones de todos los objetos binarios de Java que dependen de ellos
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)'

Qué dependencias de archivos existen ...

¿Cuál es el conjunto completo de archivos fuente Java necesarios para compilar foo?

Archivos de origen:

bazel query 'kind("source file", deps(//path/to/target/foo/...))' | grep java$

Archivos generados:

bazel query 'kind("generated file", deps(//path/to/target/foo/...))' | grep java$

¿Cuál es el conjunto completo de archivos de origen de Java necesarios para compilar las pruebas de QUX?

Archivos de origen:

bazel query 'kind("source file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

Archivos generados:

bazel query 'kind("generated file", deps(kind(".*_test rule", javatests/com/example/qux/...)))' | grep java$

¿Qué diferencias existen en las dependencias entre X e Y ...

¿Qué objetivos depende //foo de los que no depende de //foo:foolib?

bazel query 'deps(//foo) except deps(//foo:foolib)'

¿De qué bibliotecas C++ dependen las pruebas foo de las que no se basa el objeto binario de producción //foo?

bazel query 'kind("cc_library", deps(kind(".*test rule", foo/...)) except deps(//foo))'

Por qué existe esta dependencia ...

¿Por qué bar depende de groups2?

bazel query 'somepath(bar/...,groups2/...:*)'

Una vez que tengas los resultados de esta consulta, a menudo descubrirás que un solo objetivo se destaca por ser una dependencia inesperada o grave y no deseada de bar. Luego, se puede definir mejor la consulta para lo siguiente:

Mostrarme una ruta de docker/updater:updater_systest (un py_test) a algunos cc_library de la que depende:

bazel query 'let cc = kind(cc_library, deps(docker/updater:updater_systest)) in
  somepath(docker/updater:updater_systest, $cc)'

¿Por qué la biblioteca //photos/frontend:lib depende de dos variantes de la misma biblioteca //third_party/jpeglib y //third_party/jpeg?

Esta consulta se resume a lo siguiente: "muéstrame el subgráfico de //photos/frontend:lib que depende de ambas bibliotecas". Cuando se muestra en orden topológico, el último elemento del resultado es el culpable más probable.

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

Qué depende de ...

¿Qué reglas bajo la barra dependen de Y?

bazel query 'bar/... intersect allpaths(bar/..., Y)'

¿Qué objetivos dependen directamente de T, en el paquete de T?

bazel query 'same_pkg_direct_rdeps(T)'

¿Cómo rompo una dependencia ...

¿Qué rutas de acceso de dependencia debo romper para que bar ya no dependa de X?

Para generar el gráfico en un archivo svg, haz lo siguiente:

bazel query 'allpaths(bar/...,X)' --output graph | dot -Tsvg > /tmp/dep.svg

Varios

¿Cuántos pasos secuenciales hay en la compilación //foo-tests?

Por desgracia, el lenguaje de consulta actualmente no puede darte la ruta de acceso más larga de x a y, pero puede encontrar el nodo más distante (o, mejor dicho, a) desde el punto de partida o mostrarte las longitudes de la ruta de acceso más larga de x a cada y de la que depende. Usa maxrank:

bazel query 'deps(//foo-tests)' --output maxrank | tail -1
85 //third_party/zlib:zutil.c

El resultado indica que existen rutas de acceso con una longitud de 85 que deben ocurrir en orden en esta compilación.