En esta página, se explica cómo comenzar a usar el lenguaje de consulta de Bazel para rastrear dependencias en tu código.
Para obtener detalles sobre el lenguaje y la marca --output, consulta los
manuales de referencia, la referencia de la consulta 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 y, al mismo tiempo, ignorar errores como los destinos faltantes, usa la marca --keep_going.
Cómo encontrar 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.
Cómo rastrear la cadena de dependencias entre dos paquetes
La biblioteca //third_party/zlib:zlibonly no está en el archivo BUILD de //foo, pero es una dependencia indirecta. ¿Cómo podemos rastrear esta ruta de dependencia? Aquí hay dos funciones útiles: allpaths y somepath. También puedes excluir las dependencias de herramientas con --notool_deps si solo te interesa lo que se incluye en el artefacto que compilaste y no en 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 dot herramienta de línea de comandos:
$ 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 aplanada del gráfico de dependencias.
$ 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
Nota: Dependencias implícitas
El archivo BUILD de //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 tiene una dependencia implícita en el compilador de protocolos. Estas dependencias no se mencionan en el archivo de compilación, pero la herramienta de compilación las agrega. Actualmente, no se documenta el conjunto completo de dependencias implícitas. El uso de --noimplicit_deps te permite filtrar
estas dependencias de los resultados de la consulta. En el caso de cquery, esto incluirá cadenas de herramientas resueltas.
Dependencias inversas
Es posible que desees conocer el conjunto de destinos que depende de algún destino. Por ejemplo, si vas a cambiar algún código, es posible que quieras saber qué otro código estás a punto de interrumpir. Puedes usar rdeps(u, x) para encontrar las dependencias inversas de los destinos en x dentro del cierre transitivo de u.
La consulta Sky 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.
Qué 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 generan las reglas en el paquete foo?
bazel query 'kind("generated file", //foo:*)'¿Qué destinos 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 test_suite?
bazel query 'tests(//foo:smoke_tests)'
¿Cuáles de ellas son pruebas de C++?
bazel query 'kind(cc_.*, tests(//foo:smoke_tests))'
¿Cuáles de ellas son pequeñas? ¿Medianas? ¿Grandes?
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 debajo de foo que coinciden con un patrón?
bazel query 'filter("pa?t", kind(".*_test rule", //foo/...))'El patrón es una expresión regular y se aplica al nombre completo de la regla. Es similar a hacer lo siguiente:
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 para path/to/file/bar.java?
bazel query path/to/file/bar.java
¿Qué destino(s) de 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 paquetes existen ...
¿De qué paquetes depende foo? (¿Qué debo consultar para compilar foo)
bazel query 'buildfiles(deps(//foo:foo))' --output package
¿De qué paquetes depende el árbol foo, sin incluir foo/contrib?
bazel query 'deps(foo/... except foo/contrib/...)' --output package
Qué dependencias de reglas existen ...
¿De qué reglas genproto depende bar?
bazel query 'kind(genproto, deps(bar/...))'
Busca 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 busca 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 de 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 fuente 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 en las dependencias entre X y Y existen ...
¿De qué destinos depende //foo que //foo:foolib no?
bazel query 'deps(//foo) except deps(//foo:foolib)'
¿De qué bibliotecas de C++ dependen las pruebas foo de las que el objeto binario de producción //foo no depende?
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 verás que un solo destino se destaca como una dependencia inesperada o grave y no deseada de bar. Luego, la consulta se puede definir mejor de la siguiente manera:
Muéstrame una ruta de acceso desde docker/updater:updater_systest (un py_test) a algún cc_library del 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 reduce a: "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 en bar dependen de Y?
bazel query 'bar/... intersect allpaths(bar/..., Y)'
¿Qué destinos dependen directamente de T, en el paquete de T?
bazel query 'same_pkg_direct_rdeps(T)'
Cómo interrumpo una dependencia ...
¿Qué rutas de dependencia debo interrumpir 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?
Lamentablemente, el lenguaje de consulta no puede proporcionarte la ruta más larga de x a y, pero puede encontrar el nodo más distante (o más bien un nodo) desde el punto de partida o mostrarte las longitudes de la ruta 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 longitud 85 que deben ocurrir en orden en esta compilación.