Guia de consulta

Informar um problema Ver código-fonte Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

Para saber mais sobre a linguagem e a flag --output, consulte os manuais de referência Referência da consulta do Bazel e Referência da cquery do Bazel. Para receber ajuda, digite bazel help query ou bazel help cquery na linha de comando.

Para executar uma consulta ignorando erros, como alvos 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 para //foo, mas é uma dependência indireta. Como podemos rastrear esse caminho de dependência? Há duas funções úteis aqui: allpaths e somepath. Você também pode excluir dependências de ferramentas com --notool_deps se estiver interessado apenas no que está incluído no artefato criado, e não em todos os jobs possíveis.

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

$ 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, uma lista simplificada do gráfico de dependências será gerada.

$ 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

À parte: dependências implícitas

O arquivo BUILD de //foo nunca faz referência a //translations/tools:aggregator. Onde está a dependência direta?

Algumas regras incluem dependências implícitas de 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 adicionadas pela ferramenta de build. O conjunto completo de dependências implícitas ainda não está documentado. O uso de --noimplicit_deps permite filtrar essas dependências dos resultados da consulta. Para cquery, isso inclui toolchains resolvidos.

Dependências reversas

Talvez você queira saber o conjunto de destinos que depende de algum destino. Por exemplo, se você for alterar algum código, pode querer saber que outro código você está prestes a quebrar. É possível usar rdeps(u, x) para encontrar as dependências inversas das metas em x dentro do fechamento transitivo de u.

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

Usos diversos

É possível 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 estã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 são os destinos gerados pelo macro foo do Starlark?

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

Qual é o conjunto de arquivos BUILD necessário 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 das alternativas abaixo são testes de C++?

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

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

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 regex e é aplicado ao nome completo da regra. É semelhante a

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 de path/to/file/bar.java?

bazel query path/to/file/bar.java

Quais metas 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 conferir 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 regras existem ...

De quais regras de 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 do Java na árvore de servlet.

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 o 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 testes 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 são as diferenças nas dependências entre X e Y?

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/...:*)'

Com os resultados dessa consulta, você geralmente vai descobrir que um único destino se destaca como uma dependência inesperada, grave e indesejável de bar. A consulta pode então ser refinada para:

Mostre um caminho de docker/updater:updater_systest (um py_test) para algumas 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: "mostrar o subgráfico de //photos/frontend:lib que depende das duas 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 abaixo da 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 faço para interromper uma dependência ...

Quais caminhos de dependência preciso interromper 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 mostrar o caminho mais longo de x para y, mas pode encontrar o nó mais distante (ou seja, a) 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 neste build.