O modo de 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
Para ativar o modo de fornecedor, especifique a flag --vendor_dir.
Por exemplo, adicionando-o 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 à raiz do espaço de trabalho ou um caminho absoluto.
Fornecer um repositório externo específico
Você pode 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, executar:
bazel vendor --vendor_dir=vendor_src --repo=@rules_cc
ou
bazel vendor --vendor_dir=vendor_src --repo=@@rules_cc+
vai fazer com que o rules_cc seja fornecido em
<workspace root>/vendor_src/rules_cc+.
Fornecer dependências externas para determinados destinos
Para fornecer 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.
Nos bastidores, ele está executando um comando bazel build --nobuild para analisar os padrões de destino. Portanto, as flags de build podem ser aplicadas a esse comando e afetar o resultado.
Criar o destino off-line
Com as dependências externas fornecidas, você pode criar o destino off-line por
bazel build --vendor_dir=vendor_src //src/main:hello-world //src/test/...
O build precisa funcionar em um ambiente de build limpo, sem acesso à rede e cache de repositório.
Portanto, é possível fazer check-in da origem fornecida e criar os mesmos destinos off-line em outra máquina.
Fornecer todas as dependências externas
Para fornecer todos os repositórios no gráfico de dependências externas transitivas, execute:
bazel vendor --vendor_dir=vendor_src
O fornecimento de todas as dependências tem algumas desvantagens:
- Buscar todos os repositórios, incluindo aqueles introduzidos de forma transitiva, pode levar muito tempo.
- O diretório do fornecedor pode ficar muito grande.
- Alguns repositórios podem falhar na busca se não forem compatíveis com a plataforma ou o ambiente atual.
Portanto, considere fornecer para destinos específicos primeiro.
Ferramentas de fornecedor para subcomandos do Bazel
Alguns subcomandos do Bazel (como bazel mod tidy) têm dependências de ferramentas implícitas que não podem ser acessadas pelos destinos de build do usuário. Portanto, elas não são incluídas por bazel vendor //.... Para fornecer essas ferramentas também, adicione o grupo de arquivos @bazel_tools//tools:tools_for_bazel_subcommands à invocação do 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
É possível controlar como determinados repositórios são processados com o arquivo VENDOR.bazel localizado no diretório do fornecedor.
Há duas diretivas disponíveis, ambas aceitando uma lista de nomes canônicos de repositório como argumentos:
ignore(): para ignorar completamente um repositório do modo de fornecedor.pin(): para fixar um repositório na origem fornecida atual como se houvesse uma flag--override_repositorypara ele. O Bazel NÃO vai atualizar a origem fornecida para esse repositório ao executar o comando do fornecedor, a menos que ele seja desafixado. O usuário pode modificar e manter a origem fornecida para esse repositório manualmente.
Por exemplo:
ignore("@@rules_cc+")
pin("@@bazel_skylib+")
Com essa configuração:
- Os dois repositórios serão excluídos dos comandos de fornecedor subsequentes.
- O repositório
bazel_skylibserá substituído pela origem localizada no diretório do fornecedor. - O usuário pode modificar com segurança a origem fornecida de
bazel_skylib. - Para fornecer
bazel_skylibnovamente, o usuário precisa desativar a instrução de fixação primeiro.
Entender como o modo de fornecedor funciona
O Bazel busca dependências externas de um projeto em $(bazel info
output_base)/external. A disponibilização de pacotes de terceiros de dependências externas significa mover arquivos e diretórios relevantes para o diretório do fornecedor especificado e usar a origem fornecida para builds posteriores.
O conteúdo fornecido inclui:
- O diretório do repositório
- O arquivo de marcador do repositório
Durante um build, se o arquivo de marcador fornecido estiver atualizado ou o repositório estiver fixado no arquivo VENDOR.bazel, o Bazel vai usar a origem fornecida criando um link simbólico para ela em $(bazel info output_base)/external em vez de 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 repo.
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
realizar o build off-line, o Bazel fornece todos os arquivos de registro buscados na
rede no diretório <vendor_dir>/_registries.
Links simbólicos do fornecedor
Os repositórios externos podem conter links simbólicos 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 links simbólicos na origem fornecida:
- 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 fornecida, reescreva todos os links simbólicos que originalmente apontam para um
caminho em
$(bazel info output_base)/externalpara um caminho relativo em<vendor_dir>/bazel-external.
Por exemplo, se o link simbólico original for
<vendor_dir>/repo_foo+/link => $(bazel info output_base)/external/repo_bar+/file
Ele será reescrito para
<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, é
recomendado adicioná-lo a .gitignore ou equivalente para evitar o check-in.
Com essa estratégia, os links simbólicos na origem fornecida funcionarão corretamente mesmo depois que a origem fornecida for movida para outro local ou a base de saída do Bazel for alterada.