Todos os destinos pertencem a exatamente um pacote. O nome de um destino é chamado de rótulo. Cada rótulo identifica um destino. Um rótulo típico em formato canônico tem a seguinte aparência:
@myrepo//my/app/main:app_binary
A primeira parte do rótulo é o nome do repositório, @myrepo//
.
No caso típico de um rótulo se referir ao mesmo repositório em que
ele é usado, o identificador do repositório pode ser abreviado como //
.
Dentro de @myrepo
, esse rótulo geralmente é escrito como
//my/app/main:app_binary
A segunda parte do rótulo é o nome do pacote não qualificado
my/app/main
, o caminho do pacote
em relação à raiz do repositório. Juntos, o nome do repositório e o
nome do pacote não qualificado formam o nome do pacote totalmente qualificado
@myrepo//my/app/main
. Quando o rótulo se refere ao mesmo
pacote em que é usado, o nome do pacote (e, opcionalmente, dois pontos)
pode ser omitido. Portanto, em @myrepo//my/app/main
, esse rótulo pode ser escrito de uma das seguintes maneiras:
app_binary
:app_binary
É uma convenção de que o sinal de dois-pontos é omitido para arquivos, mas retido para regras, mas não é significativo.
A parte do rótulo após os dois-pontos (app_binary
) é o nome do destino não qualificado. Quando corresponde ao último componente do caminho do pacote, ele e os dois-pontos podem ser omitidos. Portanto, os dois rótulos são equivalentes:
//my/app/lib
//my/app/lib:lib
O nome de um destino de arquivo em um subdiretório do pacote é o caminho do arquivo
relacionado à raiz do pacote (o diretório que contém o arquivo BUILD
). Portanto,
esse arquivo está no subdiretório my/app/main/testdata
do repositório:
//my/app/main:testdata/input.txt
Strings como //my/app
e @some_repo//my/app
têm dois significados dependendo do contexto em que são usadas: quando o Bazel espera um rótulo, significa que //my/app:app
e @some_repo//my/app:app
, respectivamente. No entanto, quando o Bazel espera um pacote (por exemplo, nas especificações package_group
), ele faz referência ao pacote que contém esse rótulo.
Um erro comum em arquivos BUILD
é usar //my/app
para se referir a um pacote ou
todos os destinos em um pacote. Lembre-se de que é equivalente a //my/app:app
, portanto, nomeia o destino app
no pacote my/app
do repositório atual.
No entanto, o uso de //my/app
para se referir a um pacote é recomendável na especificação de um arquivo package_group
ou .bzl
, porque informa claramente que o nome do pacote é absoluto e tem acesso root ao diretório de nível superior do espaço de trabalho.
Não é possível usar rótulos relativos para destinos em outros pacotes. Nesse caso, o identificador do repositório e o nome do pacote precisam ser especificados.
Por exemplo, se a árvore de origem contiver o pacote my/app
e o
pacote my/app/testdata
(cada um desses dois diretórios tiver o próprio
arquivo BUILD
), o último pacote conterá um arquivo chamado testdepot.zip
. Veja
duas maneiras (uma incorreta, uma correta) de se referir a esse arquivo em
//my/app:BUILD
:
Incorreto: testdata
é um pacote diferente, então não é possível usar um caminho relativo.
testdata/testdepot.zip
Correto: consulte testdata
com o caminho completo.
//my/app/testdata:testdepot.zip
Os rótulos que começam com @//
são referências ao repositório
principal, que ainda funcionará mesmo em repositórios externos.
Portanto, @//a/b/c
é diferente de
//a/b/c
quando referenciado de um repositório externo.
O primeiro se refere ao repositório principal, enquanto o segundo
procura //a/b/c
no próprio repositório externo.
Isso é especialmente relevante ao gravar regras no repositório
principal que se referem a destinos no repositório principal e será
usado de repositórios externos.
Para ver informações sobre as diferentes maneiras de se referir a destinos, consulte padrões de destino.
Especificação léxica de um rótulo
A sintaxe do rótulo não incentiva o uso de metacaracteres que tenham um significado especial para o shell. Isso ajuda a evitar problemas acidentais de cotação e facilita a criação de ferramentas e scripts que manipulam rótulos, como a linguagem de consulta do Bazel.
Veja abaixo os detalhes precisos sobre os nomes de destino permitidos.
Nomes de destino: package-name:target-name
target-name
é o nome do destino no pacote. O nome de uma regra
é o valor do atributo name
na declaração da regra em um arquivo
BUILD
. O nome de um arquivo é o nome do caminho dele em relação ao diretório que contém
o arquivo BUILD
.
Os nomes de destino precisam ser compostos inteiramente de caracteres desenhados a partir do conjunto a
–z
,
A
–Z
, 0
–9
e os símbolos de pontuação !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
.
Os nomes de arquivo precisam ser nomes de caminho relativos na forma normal, o que significa que não podem
começar nem terminar com uma barra (por exemplo, /foo
e foo/
são
proibidos) nem conter várias barras consecutivas como separadores de caminho
(por exemplo, foo//bar
). Da mesma forma, as referências de nível superior (..
) e
as referências do diretório atual (./
) são proibidas.
Incorreto: não use `..` para se referir a arquivos em outros pacotes.
Correto: use `//package-name:filename`
Embora seja comum usar /
no nome de um destino de arquivo, evite usar /
nos nomes de regras. Especialmente quando a forma abreviada de um rótulo é
usada, pode confundir o leitor. O rótulo //foo/bar/wiz
é sempre uma abreviação
de //foo/bar/wiz:wiz
, mesmo que não exista esse pacote foo/bar/wiz
. Ele
nunca se refere a //foo:bar/wiz
, mesmo que esse destino exista.
No entanto, há algumas situações em que o uso de uma barra é conveniente ou até mesmo necessário. Por exemplo, o nome de determinadas regras precisa corresponder ao arquivo de origem principal, que pode residir em um subdiretório do pacote.
Nomes de pacote: //package-name:target-name
O nome de um pacote é o nome do diretório que contém o arquivo BUILD
,
em relação ao diretório de nível superior do repositório.
Por exemplo, my/app
.
Os nomes de pacotes precisam ser compostos inteiramente de caracteres desenhados a partir do conjunto
A
-Z
, a
–z
, 0
–9
, '/
', '-
', '.
', '@
' e '_
', e não podem
começar com uma barra.
Para uma linguagem com uma estrutura de diretórios significativa para o sistema de módulos (por exemplo, Java), é importante escolher nomes de diretórios que sejam identificadores válidos na linguagem.
O Bazel é compatível com destinos no pacote raiz do espaço de trabalho (por exemplo, //:foo
), mas é melhor deixar esse pacote vazio para que todos os pacotes significativos tenham nomes descritivos.
Os nomes de pacotes não podem conter a substring //
nem terminar com uma barra.
Regras
Uma regra especifica a relação entre entradas e saídas e as etapas para criar as saídas. As regras podem ser de um dos muitos tipos diferentes (às vezes chamadas de classe de regra), que produzem executáveis e bibliotecas compilados, executáveis de teste e outras saídas compatíveis, conforme descrito na Enciclopédia de build.
Os arquivos BUILD
declaram destinos invocando regras.
No exemplo abaixo, vemos a declaração do my_app
de destino
usando a regra cc_binary
.
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
Cada invocação de regra tem um atributo name
, que precisa ser um nome de destino
válido, que declara um destino no pacote
do arquivo BUILD
.
Cada regra tem um conjunto de atributos. Os atributos aplicáveis a uma determinada regra e a importância e a semântica de cada atributo são uma função do tipo da regra. Consulte a Enciclopédia de criação para ver uma lista de regras e os atributos correspondentes. Cada atributo tem um nome e um tipo. Alguns dos tipos comuns de um atributo são: número inteiro, rótulo, lista de rótulos, string, lista de strings, rótulo de saída, lista de rótulos de saída. Nem todos os atributos precisam ser especificados em todas as regras. Os atributos formam um dicionário de chaves (nomes) para valores opcionais e tipados.
O atributo srcs
presente em muitas regras tem o tipo "lista de rótulos". O
valor dele, se presente, é uma lista de rótulos, cada um sendo o nome de um destino que é
uma entrada para essa regra.
Em alguns casos, o nome do tipo de regra é um pouco arbitrário, e o mais interessante são os nomes dos arquivos gerados pela regra, o que é verdadeiro das regras gerais. Para mais informações, consulte Regras gerais: genrule.
Em outros casos, o nome é significativo: para as regras *_binary
e *_test
,
por exemplo, o nome da regra determina o nome do executável produzido
pelo build.
Esse gráfico acíclico dirigido sobre destinos é chamado de gráfico de destino ou gráfico de dependência de build e é o domínio em que a ferramenta de consulta Bazel opera.
Destinos | Arquivos BUILD |