O Bazel cria software a partir do código-fonte organizado em uma árvore de diretórios chamada de espaço de trabalho. Os arquivos de origem no espaço de trabalho são organizados em uma hierarquia aninhada de pacotes, em que cada pacote é um diretório que contém um conjunto de arquivos de origem relacionados e um arquivo BUILD
. O arquivo BUILD
especifica quais saídas de software podem ser criadas a partir da fonte.
Espaço de trabalho
Um espaço de trabalho é uma árvore de diretórios no sistema de arquivos que contém os arquivos de
origem do software que você quer criar. Cada espaço de trabalho tem um arquivo de texto chamado
WORKSPACE
que pode estar vazio ou conter referências a
dependências externas necessárias para criar as saídas.
Os diretórios que contêm um arquivo chamado WORKSPACE
são considerados a raiz de um
espaço de trabalho. Portanto, o Bazel ignora todas as árvores de diretórios em um espaço de trabalho com acesso root a um subdiretório que contém um arquivo WORKSPACE
, já que formam outro espaço de trabalho.
O Bazel também oferece suporte ao arquivo WORKSPACE.bazel
como um alias de arquivo WORKSPACE
.
Se houver ambos os arquivos, WORKSPACE.bazel
será usado.
Repositórios
O código é organizado em repositórios. O diretório que contém o arquivo WORKSPACE
é a raiz do repositório principal, também chamado de @
. Outros repositórios (externos) são definidos no arquivo WORKSPACE
usando regras de espaço de trabalho.
As regras de espaço de trabalho incluídas no Bazel estão documentadas na seção Regras de espaço de trabalho na enciclopédia do build e na documentação sobre regras incorporadas do repositório Starlark.
Como os repositórios externos são os próprios repositórios, eles geralmente contêm também um
arquivo WORKSPACE
. No entanto, esses outros arquivos WORKSPACE
são
ignorados pelo Bazel. Em particular, os repositórios que dependem transitivamente não são adicionados automaticamente.
Entrega de pacotes
A unidade principal da organização de código em um repositório é o pacote. Um pacote é uma coleção de arquivos relacionados e uma especificação de como eles podem ser usados para produzir artefatos de saída.
Um pacote é definido como um diretório que contém um arquivo chamado BUILD
(ou BUILD.bazel
). Um pacote inclui todos os arquivos do diretório, além
de todos os subdiretórios abaixo dele, exceto os que contêm um
arquivo BUILD
. Com essa definição, nenhum arquivo ou diretório pode fazer parte de
dois pacotes diferentes.
Por exemplo, na árvore de diretórios a seguir,
há dois pacotes, my/app
, e o subpacote my/app/tests
.
Observe que my/app/data
não é um pacote, mas um diretório
que pertence ao pacote my/app
.
src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc
Destinos
Um pacote é um contêiner de destinos, que são definidos no arquivo
BUILD
do pacote. A maioria dos destinos é de dois tipos principais: arquivos e regras.
Os arquivos são divididos em dois tipos. Os arquivos de origem geralmente são escritos pelos esforços das pessoas e são salvos no repositório. Os arquivos gerados, às vezes chamados de arquivos derivados ou de saída, não são verificados, mas são gerados a partir de arquivos de origem.
O segundo tipo de segmentação é declarado com uma regra. Cada instância de regra especifica a relação entre um conjunto de entrada e um conjunto de arquivos de saída. As entradas de uma regra podem ser arquivos de origem, mas também podem ser a saída de outras regras.
Na maioria dos casos, a entrada de uma regra é um arquivo de origem ou um arquivo gerado. O que importa é apenas o conteúdo desse arquivo. Esse fato facilita a substituição de um arquivo de origem complexo por um arquivo gerado por uma regra, como quando o trabalho de manter manualmente um arquivo altamente estruturado é cansativo e alguém programa um programa para derivar o arquivo. Nenhuma alteração é necessária para os consumidores desse arquivo. Por outro lado, um arquivo gerado pode ser facilmente substituído por um arquivo de origem com apenas alterações locais.
As entradas de uma regra também podem incluir outras regras. O significado preciso dessas relações geralmente é bastante complexo e dependente da linguagem ou da regra, mas de maneira intuitiva. Ele é simples: uma regra de biblioteca C++ A pode ter outra regra B da biblioteca C++ para uma entrada. O efeito dessa dependência é que os arquivos principais do B'estão disponíveis para A durante a compilação, os símbolos do B&33; estão disponíveis para A durante a vinculação e os dados do ambiente de execução da B&33;estão disponíveis para A durante a execução.
Uma variante de todas as regras é que os arquivos gerados por uma regra sempre pertencem ao mesmo pacote que a própria regra. Não é possível gerar arquivos em outro pacote. No entanto, não é incomum que as entradas de uma regra venham de outro pacote.
Grupos de pacotes são conjuntos de pacotes com a finalidade de limitar a acessibilidade
de determinadas regras. Os grupos de pacotes são definidos pela função package_group
.
Eles têm três propriedades: a lista dos pacotes que eles contêm, o nome deles e
outros grupos de pacotes que eles incluem. As únicas maneiras permitidas de se referir a elas são
do atributo visibility
das regras ou do atributo default_visibility
da função package
. Elas não geram nem consomem arquivos.
Para mais informações, consulte a
documentação do package_group
.