Nesta página, descrevemos como estender a linguagem BUILD usando macros e regras.
As extensões do Bazel são arquivos que terminam em .bzl
. Use uma instrução de carga para importar um símbolo de uma extensão.
Antes de aprender os conceitos mais avançados, faça o seguinte:
Leia sobre a linguagem Starlark, usada nos arquivos
BUILD
e.bzl
.Saiba como compartilhar variáveis entre dois arquivos
BUILD
.
Macros e regras
Uma macro é uma função que cria instâncias de regras. Há dois tipos de macros:
macros simbólicas (novidade no Bazel 8) e macros
legadas. Os dois tipos de macros são definidos de maneira diferente, mas se comportam quase da mesma forma do ponto de vista de um usuário. Uma
macro é útil quando um arquivo BUILD
está ficando muito repetitivo ou complexo, já que
permite reutilizar algum código. A função é avaliada assim que o arquivo BUILD
é lido. Depois da avaliação do arquivo BUILD
, o Bazel tem poucas informações sobre macros. Se a macro gerar um genrule
, o Bazel vai se comportar quase como se você tivesse declarado esse genrule
no arquivo BUILD
. A única exceção é que os destinos declarados em uma macro simbólica têm semântica de visibilidade especial: uma macro simbólica pode ocultar os destinos internos do restante do pacote.
Uma regra é mais eficiente do que uma macro. Ele pode acessar os internos do Bazel e ter controle total sobre o que está acontecendo. Por exemplo, ela pode transmitir informações para outras regras.
Se você quiser reutilizar uma lógica simples, comece com uma macro. Recomendamos uma macro simbólica, a menos que você precise oferecer suporte a versões mais antigas do Bazel. Se uma macro ficar complexa, é uma boa ideia transformá-la em uma regra. O suporte a um novo idioma geralmente é feito com uma regra. As regras são para usuários avançados, e a maioria das pessoas nunca vai precisar escrever uma. Elas apenas carregam e chamam regras existentes.
Modelo de avaliação
Uma build consiste em três fases.
Fase de carregamento. Primeiro, carregue e avalie todas as extensões e todos os arquivos
BUILD
necessários para a build. A execução dos arquivosBUILD
apenas instancia regras (cada vez que uma regra é chamada, ela é adicionada a um gráfico). É aqui que as macros são avaliadas.Fase de análise. O código das regras é executado (função
implementation
), e as ações são instanciadas. Uma ação descreve como gerar um conjunto de saídas de um conjunto de entradas, como "execute gcc em hello.c e receba hello.o". É necessário listar explicitamente quais arquivos serão gerados antes de executar os comandos reais. Em outras palavras, a fase de análise usa o gráfico gerado pela fase de carregamento e gera um gráfico de ação.Fase de execução. As ações são executadas quando pelo menos uma das saídas é necessária. Se um arquivo estiver faltando ou se um comando não gerar uma saída, a criação vai falhar. Os testes também são executados nessa fase.
O Bazel usa o paralelismo para ler, analisar e avaliar os arquivos .bzl
e BUILD
. Um arquivo é lido no máximo uma vez por build, e o resultado da avaliação é armazenado em cache e reutilizado. Um arquivo só é avaliado depois que todas as dependências (instruções load()
) são resolvidas. Por design, o carregamento de um arquivo .bzl
não tem efeito colateral visível. Ele apenas define valores e funções.
O Bazel tenta ser inteligente: ele usa a análise de dependência para saber quais arquivos precisam ser carregados, quais regras precisam ser analisadas e quais ações precisam ser executadas. Por exemplo, se uma regra gerar ações que não são necessárias para o build atual, elas não serão executadas.
Como criar extensões
Crie sua primeira macro para reutilizar algum código. Em seguida, saiba mais sobre macros e como usá-las para criar "verbos personalizados".
Siga o tutorial de regras para começar. Em seguida, saiba mais sobre os conceitos de regras.
Os dois links abaixo serão muito úteis ao escrever suas próprias extensões. Mantenha ao alcance:
Indo mais longe
Além de macros e regras, você pode escrever aspectos e regras de repositório.
Use o Buildifier de forma consistente para formatar e fazer lint no seu código.
Siga o guia de estilo do
.bzl
.Teste seu código.
Gere documentação para ajudar seus usuários.
Otimize a performance do seu código.
Implante suas extensões para outras pessoas.