As seções anteriores descreveram pacotes, destinos e rótulos, além do gráfico de dependência de build de forma abstrata. Esta seção descreve a sintaxe concreta usada para definir um pacote.
Por definição, todo pacote contém um arquivo BUILD, que é um programa curto.
Os arquivos BUILD são avaliados usando uma linguagem imperativa,
o Starlark.
Eles são interpretados como uma lista sequencial de instruções.
Em geral, a ordem é importante: as variáveis precisam ser definidas antes de serem
usadas, por exemplo. No entanto, a maioria dos arquivos BUILD consiste apenas em declarações de
regras de build, e a ordem relativa dessas instruções é irrelevante. O que
importa é quais regras foram declaradas e com quais valores, quando a
avaliação do pacote é concluída.
Quando uma função de regra de build, como cc_library, é executada, ela cria um
novo destino no gráfico. Esse destino pode ser referenciado posteriormente usando um rótulo.
Em arquivos BUILD simples, as declarações de regras podem ser reordenadas livremente sem
mudar o comportamento.
Para incentivar uma separação clara entre código e dados, os arquivos BUILD não podem
conter definições de função, instruções for ou if (mas as comprehensions de lista
e as expressões if são permitidas). As funções podem ser declaradas em
.bzl arquivos. Além disso, os argumentos *args e **kwargs não são
permitidos em arquivos BUILD. Em vez disso, liste todos os argumentos explicitamente.
É fundamental que os programas no Starlark não possam executar E/S arbitrária. Essa invariante
torna a interpretação de arquivos BUILD hermética, dependendo apenas de um conjunto conhecido
de entradas, o que é essencial para garantir que os builds sejam reproduzíveis.
Para mais detalhes, consulte Hermeticity.
Como os arquivos BUILD precisam ser atualizados sempre que as dependências do
código subjacente mudam, eles geralmente são mantidos por várias pessoas em uma
equipe. Os autores de arquivos BUILD precisam comentar livremente para documentar o papel
de cada destino de build, seja ele destinado ao uso público ou não, e para
documentar o papel do pacote em si.
Como carregar uma extensão
As extensões do Bazel são arquivos que terminam em .bzl. Use a instrução load para importar
um símbolo de uma extensão.
load("//foo/bar:file.bzl", "some_library")
Esse código carrega o arquivo foo/bar/file.bzl e adiciona o símbolo some_library
ao ambiente. Isso pode ser usado para carregar novas regras, funções ou constantes
(por exemplo, uma string ou uma lista). Vários símbolos podem ser importados usando
argumentos adicionais para a chamada de load. Os argumentos precisam ser literais de string
(sem variável), e as instruções load precisam aparecer no nível superior. Elas não podem estar
em um corpo de função.
O primeiro argumento de load é um rótulo que identifica um
.bzl arquivo. Se for um rótulo relativo, ele será resolvido em relação ao
pacote (não ao diretório) que contém o arquivo bzl atual. Os rótulos relativos nas
load instruções precisam usar um : inicial.
load também oferece suporte a aliases. Portanto, é possível atribuir nomes diferentes aos
símbolos importados.
load("//foo/bar:file.bzl", library_alias = "some_library")
É possível definir vários aliases em uma instrução load. Além disso, a
lista de argumentos pode conter aliases e nomes de símbolos normais. O exemplo a seguir
é perfeitamente legal. Observe quando usar aspas.
load(":my_rules.bzl", "some_rule", nice_alias = "some_other_rule")
Em um arquivo .bzl, os símbolos que começam com _ não são exportados e não podem ser
carregados de outro arquivo.
É possível usar a visibilidade de carregamento para restringir
quem pode carregar um arquivo .bzl.
Tipos de regras de build
A maioria das regras de build vem em famílias, agrupadas por
linguagem. Por exemplo, cc_binary, cc_library
e cc_test são as regras de build para binários,
bibliotecas e testes em C++, respectivamente. Outras linguagens usam o mesmo
esquema de nomenclatura, com um prefixo diferente, como java_* para
Java. Algumas dessas funções estão documentadas na
Enciclopédia de build, mas é possível
que qualquer pessoa crie novas regras.
As regras
*_binarycriam programas executáveis em uma determinada linguagem. Após um build, o executável vai residir na árvore de saída binária da ferramenta de build com o nome correspondente ao rótulo da regra. Assim,//my:programapareceria em$(BINDIR)/my/program, por exemplo.Em algumas linguagens, essas regras também criam um diretório de arquivos de execução que contém todos os arquivos mencionados em um
dataatributo pertencente à regra ou qualquer regra no fechamento transitivo de dependências. Esse conjunto de arquivos é reunido em um só lugar para facilitar a implantação na produção.As regras
*_testsão uma especialização de uma regra*_binary, usada para testes automatizados. Os testes são simplesmente programas que retornam zero em caso de sucesso.Assim como os binários, os testes também têm árvores de arquivos de execução, e os arquivos abaixo dela são os únicos que um teste pode abrir legitimamente no momento da execução. Por exemplo, um programa
cc_test(name='x', data=['//foo:bar'])pode abrir e ler$TEST_SRCDIR/workspace/foo/bardurante a execução. Cada linguagem de programação tem sua própria função de utilidade para acessar o valor de$TEST_SRCDIR, mas todas são equivalentes ao uso direto da variável de ambiente. A falha na observação da regra fará com que o teste falhe quando for executado em um host de teste remoto.As regras
*_libraryespecificam módulos compilados separadamente na linguagem de programação especificada. As bibliotecas podem depender de outras bibliotecas, e os binários e testes podem depender de bibliotecas, com o comportamento de compilação separada esperado.
| Identificadores | Dependências |
Codificação de arquivo
Os arquivos BUILD e .bzl precisam ser codificados em UTF-8, do qual o ASCII é um subconjunto válido. Sequências de bytes arbitrárias são permitidas no momento, mas podem deixar de ser
compatíveis no futuro.