Práticas recomendadas

Nesta página, presumimos que você já conhece o Bazel e fornece diretrizes e conselhos sobre como estruturar seus projetos para aproveitar ao máximo os recursos dele.

Os objetivos gerais são:

  • Usar dependências refinadas para permitir paralelismo e incrementabilidade.
  • Para manter as dependências bem encapsuladas.
  • Para tornar o código bem estruturado e testável.
  • Criar uma configuração do build que seja fácil de entender e manter.

Essas diretrizes não são requisitos: poucos projetos poderão aderir a todas elas. Como diz a página do manual do lint, "Uma recompensa especial será apresentada à primeira pessoa que produzir um programa real que não produzirá erros com uma verificação rigorosa". No entanto, a incorporação do maior número possível desses princípios deixa um projeto mais legível, menos propenso a erros e mais rápido de criar.

Esta página usa os níveis de requisitos descritos nesta RFC.

Como executar builds e testes

Um projeto precisa sempre ser capaz de executar bazel build //... e bazel test //... na ramificação estável. Os destinos necessários, mas que não são criados em determinadas circunstâncias, como que exigem sinalizações de build específicas, não são criados em uma determinada plataforma, exigem contratos de licença, precisam ser marcados da forma mais específica possível (por exemplo, "requires-osx"). Essa inclusão permite que os destinos sejam filtrados em um nível mais refinado do que a tag "manual" e possibilita que alguém inspecione o arquivo BUILD para entender as restrições de um destino.

Dependências de terceiros

É possível declarar dependências de terceiros:

  • Declare-os como repositórios remotos no arquivo WORKSPACE.
  • Ou coloque-os em um diretório chamado third_party/ no diretório do seu espaço de trabalho.

Depende de binários

Tudo deve ser construído a partir do código-fonte sempre que possível. Geralmente, isso significa que, em vez de depender de uma biblioteca some-library.so, você criaria um arquivo BUILD, criaria some-library.so a partir das origens e depender desse destino.

Sempre criar a partir da origem garante que um build não use uma biblioteca criada com sinalizações incompatíveis ou uma arquitetura diferente. Há também alguns recursos, como cobertura, análise estática ou dinâmica, que só funcionam na origem.

Controle de versões

Prefira criar todo o código do head sempre que possível. Quando as versões precisam ser usadas, evite incluir a versão no nome de destino (por exemplo, //guava, não //guava-20.0). Essa nomenclatura facilita a atualização da biblioteca (apenas um destino precisa ser atualizado). Ela também é mais resiliente a problemas de dependência de losango: se uma biblioteca depende de guava-19.0 e outra depende de guava-20.0, você pode acabar com uma biblioteca que tenta depender de duas versões diferentes. Se você criou um alias enganoso para apontar os dois destinos para uma biblioteca guava, os arquivos BUILD serão enganosos.

Como usar o arquivo .bazelrc

Para opções específicas do projeto, use o arquivo de configuração workspace/.bazelrc (consulte o formato bazelrc).

Para oferecer suporte a opções por usuário no projeto que você não quer verificar no controle de origem, inclua a linha:

try-import %workspace%/user.bazelrc

(ou qualquer outro nome de arquivo) no workspace/.bazelrc e adicione user.bazelrc ao .gitignore.

Pacotes

Todo diretório que contém arquivos compiláveis precisa ser um pacote. Se um arquivo BUILD se referir a arquivos em subdiretórios (como srcs = ["a/b/C.java"]), é um sinal de que um arquivo BUILD precisa ser adicionado a esse subdiretório. Quanto maior essa estrutura, mais dependências circulares prováveis serão criadas inadvertidamente, o escopo de uma meta vai aumentar e um número crescente de dependências reversas vai precisar ser atualizado.