Guia de consulta

Relatar um problema Conferir código-fonte Por noite · 7,3 · 7,2 · 7,1 · 7,0 · 6,5

Nesta página, você vai aprender a usar a linguagem de consulta do Bazel para rastrear dependências em seu código.

Para detalhes de idioma e da sinalização --output, consulte o Manuais de referência, Referência de consulta do Bazel e referência de cquery do Bazel. Você pode receber ajuda digitando bazel help query ou bazel help cquery no linha de comando.

Para executar uma consulta ignorando erros como alvos ausentes, use o sinalização --keep_going.

Como encontrar as dependências de uma regra

Para ver as dependências de //foo, use o 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 rastrear esse caminho de dependência? Há duas funções úteis aqui: allpaths e somepath. Também é possível excluir dependências de ferramentas com --notool_deps se você quiser apenas o que está incluído no artefato que você criou, e não todos os jobs possíveis.

Para visualizar o gráfico de todas as dependências, canalize a saída da consulta do Bazel por Com a 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, você vai receber uma lista nivelada do gráfico de dependências.

$ 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 para //foo nunca faz referência //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 protocolo Compilador. Portanto, cada regra genproto carrega uma dependência implícita na compilador de protocolo. Essas dependências não são mencionadas no arquivo de build, mas adicionados pela ferramenta de build. O conjunto completo de dependências implícitas é não está documentada no momento. O uso de --noimplicit_deps permite filtrar essas dependências dos resultados da consulta. Para o cquery, isso vai incluir conjuntos de ferramentas resolvidos.

Reverter dependências

Talvez você queira saber o conjunto de destinos que depende de algum destino. Por exemplo: Se você for alterar algum código, convém saber qual outro código que você está prestes a quebrar. Use rdeps(u, x) para encontrar o inverso dependências dos destinos no x dentro do fechamento transitivo de u.

Consulta de céu do Bazel oferece suporte à função allrdeps, que permite consultar dependências reversas em um universo que você especificar.

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 destinos são gerados pela macro 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:

Para quais testes individuais uma test_suite se 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 é um regex 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 do build 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 de foo depende, exceto 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 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$

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

Quais metas a //foo depende de //foo:foolib não?

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

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

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 ter os resultados dessa consulta, muitas vezes você descobrirá que um único se destaca como inesperado, grave e indesejável dependência de bar. A consulta pode então ser refinada para:

Mostre um caminho de docker/updater:updater_systest (uma py_test) para alguns 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-me o subgráfico de //photos/frontend:lib que depende das duas bibliotecas". Quando mostrado em ordem topológica, o último elemento do resultado é a causa 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 quebro uma dependência ...

Quais caminhos de dependência preciso quebrar para fazer com 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?

Infelizmente, a linguagem de consulta não pode fornecer o caminho mais longo no momento de x para y, mas pode encontrar o (ou melhor um) nó mais distante do ponto de partida ou mostrar os comprimentos do caminho mais longo de x a cada de que 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 devem ocorrer nesta versão.