Ele pode depender de destinos de outros projetos. Dependências desses outros projetos são chamadas de dependências externas.
O arquivo WORKSPACE
(ou WORKSPACE.bazel
) na
diretório do espaço de trabalho
diz ao Bazel como conseguir as credenciais de outros projetos de dados. Esses outros projetos podem
conter um ou mais arquivos BUILD
com destinos próprios. BUILD
arquivos em
do projeto principal pode depender desses destinos externos usando o nome de
no arquivo WORKSPACE
.
Por exemplo, suponha que há dois projetos em um sistema:
/
home/
user/
project1/
WORKSPACE
BUILD
srcs/
...
project2/
WORKSPACE
BUILD
my-libs/
Se project1
quisesse depender de um destino, :foo
, definido em
/home/user/project2/BUILD
, ele pode especificar que um repositório chamado
project2
pode ser encontrado em /home/user/project2
. Depois, as segmentações
/home/user/project1/BUILD
pode depender de @project2//:foo
.
O arquivo WORKSPACE
permite que os usuários dependam de destinos de outras partes do
ou transferidos por download da Internet. Ele usa a mesma sintaxe que BUILD
.
mas permite um conjunto diferente de regras chamadas regras de repositório (às vezes,
também conhecidas como regras do espaço de trabalho). Ele vem com alguns repositórios integrados
regras e um conjunto de repositórios Starlark incorporados
regras. Os usuários também podem criar repositórios personalizados
regras para um comportamento mais complexo.
Tipos compatíveis de dependências externas
Alguns tipos básicos de dependências externas podem ser usados:
- Dependências de outros projetos do Bazel
- Dependências de projetos que não são do Bazel
- Dependências de pacotes externos
Depende de outros projetos do Bazel
Para usar destinos de um segundo projeto do Bazel, você pode
usam
local_repository
,
git_repository
ou http_archive
para vinculá-lo simbolicamente a partir do sistema de arquivos local, referenciar um repositório git ou fazer o download
(respectivamente).
Por exemplo, suponha que você esteja trabalhando em um projeto, my-project/
, e queira
depender dos objetivos do projeto de um colega de trabalho, coworkers-project/
. Ambos
projetos usam o Bazel, para que você possa adicionar o projeto de um colega de trabalho como um
dependência e usar os destinos definidos por seu colega de trabalho
BUILD. Você adicionaria o seguinte a my_project/WORKSPACE
:
local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
)
Se seu colega de trabalho tiver uma //foo:bar
de destino, seu projeto poderá se referir a ela como
@coworkers_project//foo:bar
. Os nomes de projetos externos devem ser
nomes válidos de espaço de trabalho.
Dependendo de projetos que não sejam do Bazel
Regras prefixadas com new_
, como
new_local_repository
,
permitem que você crie destinos a partir de projetos que não usam o Bazel.
Por exemplo, suponha que você esteja trabalhando em um projeto, my-project/
, e queira
depender do projeto de um colega de trabalho, coworkers-project/
. Do seu colega de trabalho
O projeto usa make
para criar, mas você gostaria de depender de um dos arquivos .so
gerado por ele. Para fazer isso, adicione o seguinte a my_project/WORKSPACE
:
new_local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
build_file = "coworker.BUILD",
)
build_file
especifica um arquivo BUILD
a ser sobreposto no projeto existente, por
exemplo:
cc_library(
name = "some-lib",
srcs = glob(["**"]),
visibility = ["//visibility:public"],
)
Então, você pode depender de @coworkers_project//:some-lib
do
BUILD
arquivos.
Dependendo dos pacotes externos,
Artefatos e repositórios Maven
Usar o conjunto de regras rules_jvm_external
para fazer o download de artefatos de repositórios Maven e disponibilizá-los em Java
dependências.
Como buscar dependências
Por padrão, as dependências externas são buscadas conforme necessário durante bazel build
. Se
quiser pré-buscar as dependências necessárias para um conjunto específico de destinos, use
bazel fetch
Para buscar incondicionalmente todas as dependências externas, use
bazel sync
À medida que os repositórios buscados são armazenados na base de saída, a busca
acontece por espaço de trabalho.
Dependências de acompanhamento
Sempre que possível, recomendamos ter uma única política de versão no projeto. Isso é necessário para dependências que você compila e acaba no binário final. Mas, nos casos em que isso não é verdade, é possível dependências de sombra. Pense no seguinte cenário:
projeto/espaço de trabalho
workspace(name = "myproject")
local_repository(
name = "A",
path = "../A",
)
local_repository(
name = "B",
path = "../B",
)
A/ESPAÇO DE TRABALHO
workspace(name = "A")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "...",
)
B/ESPAÇO DE TRABALHO
workspace(name = "B")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
As dependências A
e B
dependem de testrunner
, mas também dependem de
versões diferentes de testrunner
. Não há motivo para estes executores de teste
não coexistem pacificamente dentro do myproject
, mas vão entrar em conflito
porque têm o mesmo nome. Para declarar as duas dependências,
atualize myproject/WORKSPACE:
workspace(name = "myproject")
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "testrunner-v1",
urls = ["https://github.com/testrunner/v1.zip"],
sha256 = "..."
)
http_archive(
name = "testrunner-v2",
urls = ["https://github.com/testrunner/v2.zip"],
sha256 = "..."
)
local_repository(
name = "A",
path = "../A",
repo_mapping = {"@testrunner" : "@testrunner-v1"}
)
local_repository(
name = "B",
path = "../B",
repo_mapping = {"@testrunner" : "@testrunner-v2"}
)
Esse mecanismo também pode ser usado para unir diamantes. Por exemplo, se A
e B
tivesse a mesma dependência, mas chamá-la por nomes diferentes, essas dependências podem
serão mesclados em myproject/WORKSPACE.
Como substituir repositórios pela linha de comando
Para substituir um repositório declarado por um repositório local na linha de comando, faça o seguinte:
use o método
--override_repository
. O uso dessa flag altera o conteúdo dos repositórios externos sem
alterar o código-fonte.
Por exemplo, para substituir @foo
pelo diretório local /path/to/local/foo
,
transmitir a flag --override_repository=foo=/path/to/local/foo
.
Alguns dos casos de uso incluem:
- Depuração de problemas. Por exemplo, é possível modificar um repositório
http_archive
para um diretório local no qual é possível fazer alterações com mais facilidade. - Fornecedores. Se você estiver em um ambiente em que não é possível fazer chamadas de rede, substitua as regras de repositório baseadas em rede para apontar para diretórios locais como alternativa.
Como usar proxies
O Bazel vai selecionar endereços proxy de HTTPS_PROXY
e HTTP_PROXY
.
variáveis de ambiente e use-as para fazer o download de arquivos HTTP/HTTPS (se especificado).
Suporte para IPv6
Em máquinas somente IPv6, o Bazel pode fazer o download de dependências com
nenhuma mudança. Em máquinas IPv4/IPv6 de pilha dupla, o Bazel segue a mesma
padrão como Java: se o IPv4 estiver ativado, o IPv4 será preferível. Em algumas situações,
por exemplo, quando a rede IPv4 não consegue resolver/alcançar endereços externos,
isso pode causar exceções Network unreachable
e falhas de build.
Nesses casos, é possível substituir o comportamento do Bazel para preferir o IPv6.
usando a propriedade do sistema java.net.preferIPv6Addresses=true
.
Especificamente:
Usar o
--host_jvm_args=-Djava.net.preferIPv6Addresses=true
opção de inicialização, por exemplo, adicionando a seguinte linha em seu Arquivo.bazelrc
:startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true
Se você estiver executando destinos de build Java que precisam se conectar à Internet. (os testes de integração às vezes precisam disso), também use
--jvmopt=-Djava.net.preferIPv6Addresses=true
sinalização de ferramenta, por exemplo, ao definir linha a seguir no seu arquivo.bazelrc
:build --jvmopt=-Djava.net.preferIPv6Addresses
Se você estiver usando rules_jvm_external, Por exemplo, para resolução da versão da dependência, adicione também
-Djava.net.preferIPv6Addresses=true
paraCOURSIER_OPTS
variável de ambiente para fornecer opções da JVM para a Coursier
Dependências transitivas
O Bazel só lê as dependências listadas no seu arquivo WORKSPACE
. Se o seu projeto
(A
) depende de outro projeto (B
), que lista uma dependência de um terceiro
projeto (C
) em seu arquivo WORKSPACE
, você terá que adicionar tanto B
e C
ao arquivo WORKSPACE
do projeto. Esse requisito pode fazer o balão
O tamanho do arquivo é WORKSPACE
, mas limita as chances de ter uma biblioteca
incluem C
na versão 1.0 e outro incluem C
na 2.0.
Armazenamento em cache de dependências externas
Por padrão, o Bazel só faz um novo download das dependências externas quando
a definição muda. Alterações nos arquivos referenciados na definição (como patches)
ou BUILD
) também são consideradas pelo Bazel.
Para forçar um novo download, use bazel sync
.
Layout
É feito o download das dependências externas em um diretório no subdiretório
external
na base de saída. No caso de um
repositório local, um link simbólico será criado.
em vez de criar um novo diretório.
Para ver o diretório external
, execute:
ls $(bazel info output_base)/external
A execução do bazel clean
não exclui o componente externo
diretório. Para remover todos os artefatos externos, use bazel clean --expunge
.
Compilações off-line
Às vezes, é desejável ou necessário executar um build de modo off-line. Para
casos de uso simples, como viajar de avião,
prefetching do que
com bazel fetch
ou bazel sync
pode ser suficiente. além do mais, os
usando a opção --nofetch
, a busca de outros repositórios poderá ser desativada
durante o build.
Para builds off-line verdadeiros, em que o fornecimento dos arquivos necessários é feito.
por uma entidade diferente do Bazel, o Bazel é compatível com a opção
--distdir
: Sempre que uma regra de repositório solicitar que o Bazel busque um arquivo pelo
ctx.download
ou
ctx.download_and_extract
e fornece uma soma hash do arquivo
necessário, o Bazel vai examinar primeiro os diretórios especificados por essa opção
um arquivo correspondente ao nome de base do primeiro URL fornecido e usar essa cópia local
se o hash corresponder.
O próprio Bazel usa essa técnica para fazer o bootstrap off-line da distribuição
artefato.
Para isso, ela coleta todas as informações
dependências
em um ambiente
distdir_tar
.
No entanto, o Bazel permite a execução de comandos arbitrários em regras de repositório, sem saber se eles pedem para a rede. Portanto, o Bazel não tem opção para fazer com que os builds sejam totalmente off-line. Testar se um build funciona corretamente off-line exige o bloqueio externo da rede, como o Bazel faz na teste de inicialização.
Práticas recomendadas
Regras do repositório
Uma regra de repositório geralmente é responsável por:
- Detectar as configurações do sistema e gravá-las em arquivos.
- Encontrar recursos em outro lugar do sistema.
- Fazendo o download de recursos de URLs.
- gerar ou fazer a vinculação simbólica de arquivos BUILD no diretório do repositório externo.
Evite usar repository_ctx.execute
sempre que possível. Por exemplo, ao usar uma linguagem C++ que não é do Bazel
que tenha um build usando o Make, é preferível usar repository_ctx.download()
e depois
grave um arquivo BUILD em vez de executar ctx.execute(["make"])
.
Prefere http_archive
a git_repository
e
new_git_repository
. Os motivos são:
- As regras de repositório Git dependem do sistema
git(1)
, enquanto o downloader HTTP é criado ao Bazel e não tem dependências de sistema. http_archive
oferece suporte a uma lista deurls
como espelhos, egit_repository
oferece suporte apenas um únicoremote
.http_archive
funciona com o cache do repositório, mas nãogit_repository
. Consulte #5116 (link em inglês) para mais informações.
Não use bind()
. Consulte "Considere remover
vinculação" por muito tempo
discussão sobre os problemas e as alternativas.