Esta página descreve 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 carregamento para importar um símbolo de uma extensão.
Antes de aprender os conceitos mais avançados, primeiro:
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 instancia regras. Ele é útil quando um
arquivo BUILD
está ficando muito repetitivo ou complexo, porque permite a reutilização
de um código. A função é avaliada assim que o arquivo BUILD
é lido. Após
a avaliação do arquivo BUILD
, o Bazel tem poucas informações sobre macros:
se sua macro gerar um genrule
, ele vai se comportar como se você tivesse escrito
genrule
. Como resultado, o bazel query
vai listar apenas os genrule
gerados.
Uma regra é mais eficiente que uma macro. Ela pode acessar os dados internos do Bazel e ter controle total sobre o que está acontecendo. Ela pode, por exemplo, transmitir informações para outras regras.
Se você quiser reutilizar uma lógica simples, comece com uma macro. Se uma macro se tornar complexa, muitas vezes é uma boa ideia torná-la uma regra. O suporte a um novo idioma costuma ser feito com uma regra. As regras são para usuários avançados, e a maioria dos usuários nunca vai precisar escrever uma. Elas só carregam e chamam as regras existentes.
Modelo de avaliação
Um 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 versão. A execução dos arquivosBUILD
simplesmente instancia regras (sempre 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 (a 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, por exemplo, "executar gcc em hello.c e get hello.o". Antes de executar os comandos reais, liste explicitamente quais arquivos serão gerados. Em outras palavras, a fase de análise pega o grafo 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 delas é necessária. Se um arquivo estiver ausente ou se um comando não gerar uma saída, o build falhará. Os testes também são executados durante essa fase.
O Bazel usa 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 é avaliado apenas depois que todas as dependências (instruções load()
)
dele forem resolvidas. Por padrão, o carregamento de um arquivo .bzl
não tem um efeito colateral visível, ele apenas define valores e funções.
O Bazel tenta ser inteligente: ele usa a análise de dependências 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 você não precisa para a versão atual, elas não serão executadas.
Como criar extensões
Crie sua primeira macro para reutilizar o código. Em seguida, saiba mais sobre macros e como usá-las para criar "verbos personalizados".
Siga o tutorial para começar. A seguir, você pode ler mais sobre os conceitos de regras.
Os dois links abaixo serão muito úteis quando você criar suas próprias extensões. Mantenha-os ao seu alcance:
Mais informações
Além de macros e regras, é recomendável escrever aspectos e regras de repositório.
Use o Buildifier de forma consistente para formatar e inspecionar o código.
Siga o guia de estilo do
.bzl
.Teste o código.
Gere documentação para ajudar seus usuários.
Otimize o desempenho do seu código.
Implante suas extensões para outras pessoas.