O modo fornecedor é um recurso que permite criar uma cópia local de dependências externas. Isso é útil para builds off-line ou quando você quer controlar a origem de uma dependência externa.
Ativar o modo de fornecedor
É possível ativar o modo de fornecedor especificando a flag --vendor_dir.
Por exemplo, adicione ao arquivo .bazelrc:
# Enable vendor mode with vendor directory under <workspace>/vendor_src
common --vendor_dir=vendor_src
O diretório do fornecedor pode ser um caminho relativo para a raiz do espaço de trabalho ou um caminho absoluto.
Fornecer um repositório externo específico
É possível usar o comando vendor com a flag --repo para especificar qual repositório
fornecer. Ele aceita o nome canônico do repositório e o nome aparente do repositório.
Por exemplo, ao executar:
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
ou
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc+
vão fazer com que rules_cc seja vendido em
<workspace root>/vendor_src/rules_cc+.
Disponibilizar pacotes de terceiros para dependências externas de determinados destinos
Para incluir todas as dependências externas necessárias para criar determinados padrões de destino, execute bazel vendor <target patterns>.
Por exemplo:
bazel vendor --vendor_dir=vendor_src //src/main:hello-world //src/test/...
vai fornecer todos os repositórios necessários para criar o destino //src/main:hello-world
e todos os destinos em //src/test/... com a configuração atual.
Por baixo dos panos, ele executa um comando bazel build --nobuild para analisar os
padrões de destino. Portanto, flags de build podem ser aplicadas a esse comando e
afetar o resultado.
Criar o destino off-line
Com as dependências externas disponibilizadas por pacotes de terceiros, é possível criar o destino off-line
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
A build precisa funcionar em um ambiente de build limpo, sem acesso à rede e cache do repositório.
Portanto, é possível fazer check-in na origem vendida e criar os mesmos destinos off-line em outra máquina.
Disponibilizar pacotes de terceiros para todas as dependências externas
Para incluir todos os repositórios no gráfico de dependências externas transitivas, execute:
bazel vendor --vendor_dir=vendor_src
Observe que a disponibilização de pacotes de terceiros de todas as dependências tem algumas desvantagens:
- Buscar todos os repositórios, incluindo os introduzidos de forma transitiva, pode levar tempo.
- O diretório do fornecedor pode ficar muito grande.
- Alguns repositórios podem não ser buscados se não forem compatíveis com a plataforma ou o ambiente atual.
Portanto, considere a disponibilização de pacotes de terceiros para metas específicas primeiro.
Ferramentas do fornecedor para subcomandos do Bazel
Alguns subcomandos do Bazel (como bazel mod tidy) têm dependências implícitas de ferramentas que não podem ser acessadas de destinos de build do usuário. Portanto, elas não são incluídas por bazel vendor //.... Para vender essas ferramentas também, adicione
o grupo de arquivos @bazel_tools//tools:tools_for_bazel_subcommands à sua
invocação de fornecedor:
bazel vendor //... @bazel_tools//tools:tools_for_bazel_subcommands
Isso é necessário se você planeja executar comandos como bazel mod tidy em um ambiente
off-line ou hermético (por exemplo, com --vendor_dir e
--nofetch).
Configurar o modo de fornecedor com VENDOR.bazel
Você pode controlar como determinados repositórios são processados com o arquivo VENDOR.bazel localizado no diretório vendor.
Há duas diretivas disponíveis, ambas aceitando uma lista de nomes canônicos de repositórios como argumentos:
ignore(): para ignorar completamente um repositório do modo do fornecedor.pin(): para fixar um repositório na origem vendida atual como se houvesse uma flag--override_repositorypara esse repositório. O Bazel NÃO vai atualizar a origem vendida para este repositório ao executar o comando de venda, a menos que ela seja desfixada. O usuário pode modificar e manter manualmente a origem vendida para esse repositório.
Por exemplo:
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
Com essa configuração
- Ambos os repositórios serão excluídos dos comandos subsequentes do fornecedor.
- O Repo
bazel_skylibserá substituído pela origem localizada no diretório vendor. - O usuário pode modificar com segurança a origem vendida de
bazel_skylib. - Para fazer isso, o usuário precisa desativar a declaração de PIN primeiro.
bazel_skylib
Entenda como o modo do fornecedor funciona
O Bazel busca dependências externas de um projeto em $(bazel info
output_base)/external. Fazer o vendoring de dependências externas significa mover
arquivos e diretórios relevantes para o diretório de fornecedor especificado e usar a
origem vendored para builds posteriores.
O conteúdo vendido inclui:
- O diretório do repositório
- O arquivo de marcador do repositório
Durante um build, se o arquivo marcador vendido estiver atualizado ou se o repositório estiver
fixado no arquivo VENDOR.bazel, o Bazel usará a origem vendida criando
um link simbólico para ela em $(bazel info output_base)/external em vez de realmente
executar a regra do repositório. Caso contrário, um aviso será mostrado, e o Bazel vai
voltar a buscar a versão mais recente do repositório.
Arquivos de registro do fornecedor
O Bazel precisa realizar a resolução do módulo para buscar dependências externas, o que pode exigir o acesso a arquivos de registro pela Internet. Para
fazer um build off-line, o Bazel vende todos os arquivos de registro buscados da
rede no diretório <vendor_dir>/_registries.
Symlinks de fornecedores
Repositórios externos podem conter symlinks que apontam para outros arquivos ou diretórios. Para garantir que os links simbólicos funcionem corretamente, o Bazel usa a seguinte estratégia para reescrever os links simbólicos na origem vendida:
- Crie um link simbólico
<vendor_dir>/bazel-externalque aponte para$(bazel info output_base)/external. Ele é atualizado automaticamente por todos os comandos do Bazel. - Para a origem vendida, reescreva todos os links simbólicos que apontam originalmente para um
caminho em
$(bazel info output_base)/externalpara um caminho relativo em<vendor_dir>/bazel-external.
Por exemplo, se o symlink original for
<vendor_dir>/repo_foo+/link => $(bazel info output_base)/external/repo_bar+/file
Ele será reescrito como
<vendor_dir>/repo_foo+/link => ../../bazel-external/repo_bar+/file
onde
<vendor_dir>/bazel-external => $(bazel info output_base)/external # This might be new if output base is changed
Como <vendor_dir>/bazel-external é gerado automaticamente pelo Bazel, é recomendável adicioná-lo a .gitignore ou equivalente para evitar o check-in.
Com essa estratégia, os symlinks na origem vendida funcionam corretamente mesmo depois que ela é movida para outro local ou a base de saída do Bazel é alterada.