Práticas recomendadas

Esta página pressupõe que você já conhece o Bazel e oferece diretrizes e conselhos sobre como estruturar seus projetos para aproveitar ao máximo os recursos do Bazel.

Os objetivos gerais são:

  • Usar dependências refinadas para permitir paralelismo e incrementalidade.
  • Manter as dependências bem encapsuladas.
  • Deixar o código bem estruturado e testável.
  • Criar uma configuração de build 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 de manual do lint, "Um prêmio especial será apresentado à primeira pessoa que produzir um programa real que não gere erros com a verificação estrita." No entanto, incorporar o máximo possível desses princípios deve tornar 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 em nesta RFC.

Execução de builds e testes

Um projeto sempre precisa executar bazel build //... e bazel test //... com sucesso na ramificação estável. Os destinos necessários mas que não são criados em determinadas circunstâncias (por exemplo, exigem flags 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 marcação permite que os destinos sejam filtrados em um nível mais refinado do que a tag "manual" e permite que alguém que inspeciona o BUILD entenda quais são as restrições de um destino.

Dependências de terceiros

Você pode declarar dependências de terceiros:

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

Depender de binários

Sempre que possível, tudo precisa ser criado a partir da origem. Geralmente, isso significa que, em vez de depender de uma biblioteca some-library.so, você cria um BUILD arquivo e cria some-library.so nas origens e, em seguida, depende desse destino.

A criação sempre a partir da origem garante que um build não esteja usando uma biblioteca que foi criada com flags incompatíveis ou uma arquitetura diferente. Há também alguns recursos, como cobertura, análise estática ou análise dinâmica, que só funcionam na origem.

Controle de versões

Sempre que possível, crie todo o código a partir do cabeçalho. Quando as versões precisam ser usadas, evite incluir a versão no nome do 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 diamante: 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 seu workspace/.bazelrc (consulte o formato bazelrc).

Se você quiser oferecer suporte a opções por usuário para seu projeto que você não quer fazer check-in 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 seu .gitignore.

Pacotes

Cada diretório que contém arquivos criáveis precisa ser um pacote. Se um BUILD arquivo se referir a arquivos em subdiretórios (por exemplo, srcs = ["a/b/C.java"]), isso indica que um BUILD arquivo precisa ser adicionado a esse subdiretório. Quanto mais tempo essa estrutura existir, maior será a probabilidade de dependências circulares serem criadas inadvertidamente, o escopo de um destino será ampliado e um número crescente de dependências inversas terá que ser atualizado.