Guia de consulta

Esta página aborda como começar a usar a linguagem de consulta do Bazel para rastrear dependências no seu código.

Para detalhes sobre a linguagem e a flag --output, consulte os manuais de referência, a referência de consulta do Bazel e a referência de cquery do Bazel. Você pode receber ajuda digitando bazel help query ou bazel help cquery na linha de comando.

Para executar uma consulta ignorando erros, como destinos ausentes, use a flag --keep_going.

Como encontrar as dependências de uma regra

Para conferir as dependências de //foo, use a função deps na consulta do Bazel:

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

Esse é o conjunto de todos os destinos necessários para criar //foo.

Como rastrear a cadeia de dependências entre dois pacotes

A biblioteca //third_party/zlib:zlibonly não está no arquivo BUILD de //foo, mas é uma dependência indireta. Como podemos rastrear esse caminho de dependência? Há duas funções úteis aqui: allpaths e somepath. Talvez você também queira excluir dependências de ferramentas com --notool_deps se só se importar com o que está incluído no artefato criado, e não com todos os jobs possíveis.

Para visualizar o gráfico de todas as dependências, canalize a saída da consulta do Bazel por a dot ferramenta de linha de comando:

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

Quando um gráfico de dependência é grande e complicado, pode ser útil começar com um único caminho:

$ 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

Se você não especificar --output graph com allpaths, vai receber uma lista nivelada do gráfico de dependência.

$ 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

Observação: dependências implícitas

O arquivo BUILD de //foo nunca faz referência a //translations/tools:aggregator. Então, onde está a dependência direta?

Algumas regras incluem dependências implícitas em outras bibliotecas ou ferramentas. Por exemplo, para criar uma regra genproto, primeiro é necessário criar o compilador de protocolo. Portanto, cada regra genproto tem uma dependência implícita no compilador de protocolo. Essas dependências não são mencionadas no arquivo de build, mas são adicionadas pela ferramenta de build. O conjunto completo de dependências implícitas não está documentado no momento. O uso de --noimplicit_deps permite filtrar essas dependências dos resultados da consulta. Para cquery, isso vai incluir cadeias de ferramentas resolvidas.

Dependências inversas

Talvez você queira saber o conjunto de destinos que dependem de algum destino. Por exemplo, se você for mudar algum código, talvez queira saber qual outro código vai quebrar. Você pode usar rdeps(u, x) para encontrar as dependências inversas dos destinos em x no fechamento transitivo de u.

A consulta do Sky do Bazel oferece suporte à função allrdeps, que permite consultar dependências inversas em um universo especificado.

Outros usos

Você pode usar bazel query para analisar muitas relações de dependência.

O que existe ...

Quais pacotes existem abaixo de foo?

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

Quais regras são definidas no pacote foo?

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

Quais arquivos são gerados por regras no pacote foo?

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

Quais destinos são gerados pela macro do Starlark foo?

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

Qual é o conjunto de arquivos BUILD necessários para criar //foo?

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

Quais são os testes individuais que um test_suite expande?

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

Quais deles são testes em C++?

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

Quais deles são pequenos? Médios? 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))'

Quais são os testes abaixo de foo que correspondem a um padrão?

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

O padrão é uma expressão regular e é aplicado ao nome completo da regra. É semelhante a fazer

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

Qual pacote contém o arquivo path/to/file/bar.java?

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

Qual é o rótulo de build para path/to/file/bar.java?

bazel query path/to/file/bar.java

Quais destinos de regra contêm o arquivo path/to/file/bar.java como origem?

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

Quais dependências de pacote existem ...

De quais pacotes foo depende? (O que preciso fazer para criar foo)

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

De quais pacotes a árvore foo depende, excluindo foo/contrib?

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

Quais dependências de regra existem ...

De quais regras genproto a barra depende?

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

Encontre a definição de alguma biblioteca JNI (C++) que depende transitivamente de uma regra binária Java na árvore de servlets.

bazel query 'some(kind(cc_.*library, deps(kind(java_binary, //java/com/example/frontend/...))))' --output location
...Agora encontre as definições de todos os binários Java que dependem deles
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)'

Quais dependências de arquivo existem ...

Qual é o conjunto completo de arquivos de origem Java necessários para criar foo?

Arquivos de origem:

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

Arquivos gerados:

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

Qual é o conjunto completo de arquivos de origem Java necessários para criar os testes do QUX?

Arquivos de origem:

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

Arquivos gerados:

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

Quais diferenças nas dependências entre X e Y existem ...

De quais destinos //foo depende que //foo:foolib não depende?

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

De quais bibliotecas C++ os testes foo dependem que o binário de produção //foo não depende?

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

Por que essa dependência existe ...

Por que bar depende de groups2?

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

Depois de receber os resultados dessa consulta, você geralmente vai descobrir que um único destino se destaca como uma dependência inesperada ou flagrante e indesejável de bar. A consulta pode ser refinada ainda mais para:

Mostre um caminho de docker/updater:updater_systest (um py_test) para algum cc_library de que ele depende:

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

Por que a biblioteca //photos/frontend:lib depende de duas variantes da mesma biblioteca //third_party/jpeglib e //third_party/jpeg?

Essa consulta se resume a: "mostre o subgrafo de //photos/frontend:lib que depende de ambas as bibliotecas". Quando mostrado em ordem topológica, o último elemento do resultado é o culpado mais provável.

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

O que depende de ...

Quais regras em barra dependem de Y?

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

Quais destinos dependem diretamente de T, no pacote de T?

bazel query 'same_pkg_direct_rdeps(T)'

Como quebrar uma dependência ...

Quais caminhos de dependência preciso quebrar para que bar não dependa mais de X?

Para gerar o gráfico em um arquivo svg:

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

Diversos

Quantas etapas sequenciais há no build //foo-tests?

No momento, a linguagem de consulta não pode fornecer o caminho mais longo de x para y, mas pode encontrar o nó mais distante (ou melhor, um) do ponto de partida ou mostrar os comprimentos do caminho mais longo de x para cada y de que ele depende. Use maxrank:

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

O resultado indica que existem caminhos de comprimento 85 que precisam ocorrer em ordem nesse build.