O Bazel oferece suporte a dependências externas, os arquivos de origem (de texto e binários) usados. do build que não são do seu espaço de trabalho. Por exemplo, eles podem ser um conjunto de regras hospedado em um repositório do GitHub, um artefato Maven ou um diretório na sua máquina fora do seu espaço de trabalho atual.
A partir do Bazel 6.0, há duas maneiras de gerenciar dependências externas:
o sistema WORKSPACE
tradicional
e baseado em repositórios;
o sistema MODULE.bazel
mais recente focado em módulo (codinome Bzlmod),
e ativados com a flag --enable_bzlmod
). Os dois sistemas podem ser usados
juntos, mas o Bzlmod está substituindo o sistema WORKSPACE
no futuro Bazel
versões, confira o guia de migração Bzlmod para saber como
migram.
Este documento explica os conceitos relacionados ao gerenciamento de dependências externas no Bazel, antes de entrar em mais detalhes sobre os dois sistemas em ordem.
Conceitos
Repositório
Uma árvore de diretórios com um arquivo de marcador de limite na raiz, contendo o código-fonte que podem ser usados em uma versão do Bazel. Geralmente encurtado para apenas repo.
Um arquivo de marcador de limite do repositório pode ser MODULE.bazel
, indicando que esse repositório
representa um módulo do Bazel), REPO.bazel
(confira abaixo) ou
contextos legados, WORKSPACE
ou WORKSPACE.bazel
. Qualquer arquivo de marcador de limite do repositório
significa os limites de um repositório; vários desses arquivos podem coexistir
diretório.
Repositório principal
O repositório em que o comando atual do Bazel está sendo executado.
Espaço de trabalho
O ambiente compartilhado por todos os comandos do Bazel é executado no mesmo repositório principal.
Historicamente, os conceitos de "repositório" e "workspace" foram misturado; o termo "espaço de trabalho" tem sido usada muitas vezes para se referir ao principal repositório e às vezes usada até mesmo como sinônimo de "repositório".
Nome do repositório canônico
O nome canônico pelo qual um repositório é endereçável. No contexto de um
espaço de trabalho, cada repositório tem um único nome canônico. Um destino dentro de um repositório
cujo nome canônico é canonical_name
pode ser tratado pelo rótulo
@@canonical_name//pac/kage:target
(observe o @
duplo).
O repositório principal sempre tem a string vazia como nome canônico.
Nome do repositório aparente
O nome pelo qual um repositório é endereçável no contexto de outro repositório.
Isso pode ser considerado o "apelido" do repositório: o repositório com o nome canônico.
michael
pode ter o nome aparente mike
no contexto do repo
alice
, mas pode ter o nome aparente mickey
no contexto do repo
bob
. Nesse caso, um destino dentro de michael
pode ser tratado pelo rótulo.
@mike//pac/kage:target
no contexto de alice
(observe o único @
).
Por outro lado, isso pode ser entendido como um mapeamento de repositório: cada repositório mantém um mapeamento do "nome do repositório aparente" para um "nome de repositório canônico".
Regra de repositório
Um esquema para definições de repositório que informa ao Bazel como materializar um
repositório de dados. Por exemplo, pode ser "fazer o download de um arquivo zip de um determinado URL
e extraí-lo" ou "buscar um determinado artefato Maven e disponibilizá-lo como
java_import
destino" ou simplesmente "vincular simbólico a um diretório local". Cada repositório é
definida chamando uma regra de repo com um número apropriado de argumentos.
Consulte Regras de repositório para mais informações sobre como gravar suas próprias regras de repositório.
As regras de repositório mais comuns são, de longe,
http_archive
, que faz o download de um arquivo
de um URL e o extrai,
local_repository
, que cria um link simbólico para um
diretório local que já é um repositório do Bazel.
Buscar um repositório
A ação de disponibilizar um repositório no disco local executando o respectivo repositório regra repo. Os repositórios definidos em um espaço de trabalho não estão disponíveis no disco local antes de serem buscados.
Normalmente, o Bazel só busca um repositório quando precisa de algo. e o repositório ainda não foi buscado. Se o repositório já tiver sido buscado antes, ele só será buscado novamente se a definição tiver sido alterada.
O comando fetch
pode ser usado para iniciar uma pré-busca de um repositório.
destino ou todos os repositórios necessários para executar qualquer build. Essa capacidade
ativa builds off-line usando a opção --nofetch
.
A opção --fetch
serve para gerenciar o acesso à rede. Seu valor padrão é verdadeiro.
No entanto, quando definido como falso (--nofetch
), o comando vai usar qualquer
versão da dependência. Se nenhuma existir, o comando resultará em
falha.
Consulte as opções de busca para informações sobre como controlar a busca.
Layout do diretório
Após ser buscado, o repo pode ser encontrado no subdiretório external
na
output base, sob seu nome canônico.
Execute o comando a seguir para conferir o conteúdo do repositório com a
nome canônico canonical_name
:
ls $(bazel info output_base)/external/ canonical_name
Arquivo REPO.bazel
O arquivo REPO.bazel
é usado para marcar o limite superior da árvore de diretórios.
que constitui um repositório. Ele não precisa conter nada para servir como repositório.
arquivo de limite No entanto, ele também pode ser usado para especificar
para todos os destinos de build dentro do repositório.
A sintaxe de um arquivo REPO.bazel
é semelhante à dos arquivos BUILD
, exceto pelo fato de que
As instruções load
são compatíveis, e somente uma função, repo()
, é
disponíveis. repo()
usa os mesmos argumentos que a package()
.
em arquivos BUILD
. enquanto package()
especifica atributos comuns para todos os destinos de build dentro do pacote, repo()
faz isso de forma análoga para todos os destinos de compilação dentro do repositório.
Por exemplo, é possível especificar uma licença comum para todos os destinos no seu repositório
com o seguinte arquivo REPO.bazel
:
repo(
default_package_metadata = ["//:my_license"],
)
Gerenciar dependências externas com o Bzlmod
O Bzlmod, o novo subsistema de dependência externa, não funciona diretamente com o repo. e definições. Em vez disso, ele cria um gráfico de dependência de módulos e executa extensions sobre o gráfico e define os repositórios de acordo.
Um módulo (em inglês) do Bazel é um projeto do Bazel que pode ter várias
versões, e cada uma delas publica metadados sobre outros módulos de que depende
Um módulo precisa ter um arquivo MODULE.bazel
na raiz do repositório, ao lado do
arquivo WORKSPACE
. Esse arquivo é o manifesto do módulo, que declara o nome dele,
versão, lista de dependências, entre outras informações. Confira abaixo
exemplo:
module(name = "my-module", version = "1.0")
bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")
Um módulo deve listar apenas suas dependências diretas, que o Bzlmod procura em um
Registro do Bazel: por padrão, o Bazel Central
Registry. O registro fornece
dependências" MODULE.bazel
, que permitem ao Bazel descobrir todo o
gráfico de dependência transitivo antes de realizar a resolução da versão.
Após a resolução de versão, em que uma versão é selecionada para cada módulo.
O Bazel consulta o registro novamente para aprender a definir um repositório para cada módulo.
(na maioria dos casos, usando http_archive
).
Os módulos também podem especificar dados personalizados chamados tags, que são consumida por extensões de módulo após a resolução do módulo. para definir repositórios adicionais. Essas extensões têm recursos semelhantes aos de entrada e saída, permitindo que elas realizem ações como E/S de arquivos e envio de solicitações. Entre outras coisas, eles permitem que o Bazel interaja com outros de gerenciamento de identidade, respeitando o gráfico de dependência criado no Bazel. módulos.
Links externos no Bzlmod
- Exemplos de uso do Bzlmod em bazelbuild/examples (em inglês)
- Revisão das dependências externas do Bazel (documento original de design Bzlmod)
- Palestra da BazelCon 2021 sobre a Bzlmod
- Palestra do Dia da Comunidade do Bazel no Bzlmod
Definir repositórios com WORKSPACE
Antes, era possível gerenciar dependências externas definindo repositórios no
WORKSPACE
(ou WORKSPACE.bazel
). Esse arquivo tem uma sintaxe parecida com a
BUILD
, empregando regras de repositório em vez de regras de build.
O snippet a seguir é um exemplo de uso da regra de repositório http_archive
na
Arquivo WORKSPACE
:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "foo",
urls = ["https://example.com/foo.zip"],
sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)
O snippet define um repositório com o nome canônico foo
. No WORKSPACE
sistema, por padrão, o nome canônico de um repositório também é o nome aparente dele para
todos os outros repositórios.
Veja a lista completa das funções disponíveis no
WORKSPACE
.
Falhas no sistema do WORKSPACE
Nos anos desde o lançamento do sistema WORKSPACE
, os usuários relataram
muitos aspectos problemáticos, incluindo:
- O Bazel não avalia os arquivos
WORKSPACE
de nenhuma dependência. Portanto, as dependências transitivas precisam ser definidas no arquivoWORKSPACE
da instância repositório, além das dependências diretas. - Para contornar isso, os projetos adotaram a abordagem "deps.bzl" padrão, em que
ele define uma macro que, por sua vez, define vários repositórios e solicita que os usuários
chamar essa macro nos arquivos
WORKSPACE
.- Isso tem seus próprios problemas: as macros não podem
load
outros arquivos.bzl
, portanto esses projetos precisam definir suas dependências transitivas "deps" ou contornar esse problema fazendo com que o usuário chame várias "deps" em camadas . - O Bazel avalia o arquivo
WORKSPACE
sequencialmente. Além disso, dependências são especificadas usandohttp_archive
com URLs, sem nenhuma informações de versão. Isso significa que não há uma maneira confiável de realizar resolução da versão no caso de dependências diamantes (A
dependeB
eC
;B
eC
dependem de versões diferentes deD
.
- Isso tem seus próprios problemas: as macros não podem
Devido às falhas do WORKSPACE, o Bzlmod vai substituir o WORKSPACE em versões futuras do Bazel. Leia a migração Bzlmod guia sobre como migrar para o Bzlmod.