Bazel puede depender de destinos de otros proyectos. Dependencias de estos otros Los proyectos se denominan dependencias externas.
El archivo WORKSPACE
(o el archivo WORKSPACE.bazel
) de la
directorio del espacio de trabajo
le indica a Bazel cómo obtener las capacidades de otros fuentes de datos. Estos otros proyectos también pueden
contener uno o más archivos BUILD
con sus propios destinos BUILD
archivos en
el proyecto principal puede depender de estos objetivos externos mediante el uso de su nombre de
el archivo WORKSPACE
.
Por ejemplo, supongamos que hay dos proyectos en un sistema:
/
home/
user/
project1/
WORKSPACE
BUILD
srcs/
...
project2/
WORKSPACE
BUILD
my-libs/
Si project1
quisiera depender de un destino, :foo
, que se define en
/home/user/project2/BUILD
, podría especificar que un repositorio llamado
project2
se puede encontrar en /home/user/project2
. Luego, se orienta en
/home/user/project1/BUILD
podría depender de @project2//:foo
.
El archivo WORKSPACE
permite que los usuarios dependan de objetivos de otras partes de la
en un sistema de archivos
o que se descargan de Internet. Usa la misma sintaxis que BUILD
.
archivos, pero permite un conjunto diferente de reglas llamadas reglas de repositorio (a veces
también conocidas como reglas del lugar de trabajo). Bazel incluye algunas
reglas de repositorio integradas y un conjunto
reglas de repositorio de Starlark incorporadas.
Los usuarios también pueden escribir reglas de repositorio personalizadas.
para conseguir un comportamiento más complejo.
Tipos de dependencias externas compatibles
Se pueden usar algunos tipos básicos de dependencias externas:
- Dependencias en otros proyectos de Bazel
- Dependencias en proyectos que no son de Bazel
- Dependencias en paquetes externos
Según otros proyectos de Bazel
Si quieres usar destinos de otro proyecto de Bazel, puedes
usar
local_repository
:
git_repository
o http_archive
para crear un symlink desde el sistema de archivos local, hacer referencia a un repositorio de Git o descargarlo
(respectivamente).
Por ejemplo, supongamos que trabajas en un proyecto, my-project/
, y quieres
dependerá de los objetivos del proyecto de tu compañero de trabajo, coworkers-project/
. Ambas opciones
proyectos usan Bazel, por lo que puedes agregar el proyecto de tu compañero de trabajo como un
y usar cualquier objetivo que tu compañero de trabajo haya definido a partir de tu propio
Compilar archivos. Agregarías lo siguiente a my_project/WORKSPACE
:
local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
)
Si tu compañero de trabajo tiene un //foo:bar
de destino, tu proyecto puede referirse a él como
@coworkers_project//foo:bar
Los nombres de proyectos externos
nombres de lugares de trabajo válidos.
Según proyectos que no sean de Bazel
Las reglas con el prefijo new_
, como
new_local_repository
,
te permiten crear destinos a partir de proyectos que no usan Bazel.
Por ejemplo, supongamos que trabajas en un proyecto, my-project/
, y quieres
dependerá del proyecto de tu compañero de trabajo, coworkers-project/
. La dirección de tu compañero de trabajo
El proyecto usa make
para compilar, pero quieres depender de uno de los archivos .so.
que genera. Para ello, agrega lo siguiente a my_project/WORKSPACE
:
new_local_repository(
name = "coworkers_project",
path = "/path/to/coworkers-project",
build_file = "coworker.BUILD",
)
build_file
especifica un archivo BUILD
para superponer en el proyecto existente, por
ejemplo:
cc_library(
name = "some-lib",
srcs = glob(["**"]),
visibility = ["//visibility:public"],
)
Luego, puedes depender de @coworkers_project//:some-lib
de la red
BUILD
archivos.
Según los paquetes externos
Artefactos y repositorios de Maven
Usa el conjunto de reglas rules_jvm_external
.
para descargar artefactos de repositorios de Maven y ponerlos a disposición como Java
dependencias.
Recupera dependencias
De forma predeterminada, las dependencias externas se recuperan según sea necesario durante bazel build
. Si
Si quieres cargar previamente las dependencias necesarias para un conjunto específico de destinos, usa
bazel fetch
Para recuperar incondicionalmente todas las dependencias externas, usa
bazel sync
Como los repositorios recuperados se almacenan en la base de salida, recuperar
ocurre por lugar de trabajo.
Dependencias de la duplicación
Siempre que sea posible, se recomienda tener una política de versión única en tu en un proyecto final. Esto es necesario para las dependencias con las que compilas y terminas en tu objeto binario final. Pero en los casos en los que esto no sea así, es posible dependencias shadow. Considera la siguiente situación:
miproyecto/WORKSPACE
workspace(name = "myproject")
local_repository(
name = "A",
path = "../A",
)
local_repository(
name = "B",
path = "../B",
)
A/WORKSPACE
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/WORKSPACE
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 = "..."
)
Ambas dependencias, A
y B
, dependen de testrunner
, pero dependen de
diferentes versiones de testrunner
. No hay motivo para que estos ejecutores de pruebas
no coexisten pacíficamente en myproject
; sin embargo, se enfrentarán con cada una
porque tienen el mismo nombre. Para declarar ambas dependencias,
actualiza 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"}
)
Este mecanismo también se puede utilizar para unir diamantes. Por ejemplo, si A
y B
tenían la misma dependencia, pero la llamaron con nombres diferentes, esas dependencias pueden
unirme en myproject/WORKSPACE.
Anula repositorios desde la línea de comandos
Para anular un repositorio declarado con un repositorio local desde la línea de comandos,
usa el
--override_repository
marca. El uso de esta marca cambia el contenido de los repositorios externos sin
sin modificar tu código fuente.
Por ejemplo, para anular @foo
en el directorio local /path/to/local/foo
, usa este código:
pasa la marca --override_repository=foo=/path/to/local/foo
.
A continuación, se presentan algunos de los casos prácticos:
- Problemas de depuración. Por ejemplo, puedes anular un repositorio de
http_archive
. a un directorio local en el que puedas realizar cambios con mayor facilidad. - Proveedores Si estás en un entorno en el que no puedes hacer llamadas de red anular las reglas de repositorio basadas en la red para que apunten a directorios locales en su lugar.
Usa proxies
Bazel captará las direcciones de proxy de HTTPS_PROXY
y HTTP_PROXY
.
variables de entorno y usarlas para descargar archivos HTTP/HTTPS (si se especifican).
Compatibilidad con IPv6
En máquinas que solo usan IPv6, Bazel podrá descargar dependencias con
sin cambios. Sin embargo, en las máquinas IPv4/IPv6 de pila doble, Bazel sigue el mismo procedimiento
como Java: si se habilita IPv4, se prefiere IPv4. En algunas situaciones,
Por ejemplo, cuando la red IPv4 no puede resolver
o llegar a direcciones externas
Esto puede causar excepciones Network unreachable
y fallas de compilación.
En estos casos, puedes anular el comportamiento de Bazel y dar prioridad a IPv6.
Mediante la propiedad del sistema java.net.preferIPv6Addresses=true
En particular, haz lo siguiente:
Usa
--host_jvm_args=-Djava.net.preferIPv6Addresses=true
opción de inicio, por ejemplo, agregando la siguiente línea en tu Archivo.bazelrc
:startup --host_jvm_args=-Djava.net.preferIPv6Addresses=true
Si ejecutas destinos de compilación de Java que necesitan conectarse a Internet (a veces, se necesita para las pruebas de integración); también usa
--jvmopt=-Djava.net.preferIPv6Addresses=true
marca de herramienta, por ejemplo, haciendo que siguiente línea en tu archivo.bazelrc
:build --jvmopt=-Djava.net.preferIPv6Addresses
Si utilizas rules_jvm_external, p. ej., para la resolución de la versión de la dependencia, agrega
-Djava.net.preferIPv6Addresses=true
aCOURSIER_OPTS
variable de entorno para proporcionar opciones de JVM para Coursier
Dependencias transitivas
Bazel solo lee las dependencias que se indican en tu archivo WORKSPACE
. Si tu proyecto
(A
) depende de otro proyecto (B
) que indica una dependencia de un tercero
proyecto (C
) en su archivo WORKSPACE
, deberás agregar B
y C
al archivo WORKSPACE
de tu proyecto. Este requisito puede inflar
WORKSPACE
, pero limita las posibilidades de tener una biblioteca
Incluye C
en la versión 1.0 y otro incluye C
en la versión 2.0.
Almacenamiento en caché de dependencias externas
De forma predeterminada, Bazel solo volverá a descargar dependencias externas si sus
cambios en las definiciones. Cambios en los archivos a los que se hace referencia en la definición (como parches)
o archivos BUILD
) también las tiene en cuenta Bazel.
Para forzar una nueva descarga, usa bazel sync
.
Diseño
Todas las dependencias externas se descargan en un directorio en el subdirectorio
external
en la base de salida. En caso de una
repositorio local, se crea un symlink
en lugar de crear un directorio nuevo.
Para ver el directorio external
, ejecuta lo siguiente:
ls $(bazel info output_base)/external
Ten en cuenta que ejecutar bazel clean
no borrará el almacenamiento
. Para quitar todos los artefactos externos, usa bazel clean --expunge
.
Compilaciones sin conexión
A veces, es conveniente o necesario ejecutar una compilación sin conexión. Para
casos de uso sencillos, como viajar en un avión,
prefetching de los elementos
los repositorios con bazel fetch
o bazel sync
pueden ser suficientes; además, el
Con la opción --nofetch
, se puede inhabilitar la recuperación de más repositorios
durante la compilación.
Para compilaciones sin conexión reales, en las que se deben proporcionar los archivos necesarios
por una entidad diferente de bazel, bazel admite la opción
--distdir
Cuando una regla de repositorio le pide a Bazel que recupere un archivo mediante
ctx.download
o
ctx.download_and_extract
y proporciona una suma hash del archivo
necesario, Bazel primero buscará en los directorios especificados por esa opción para
un archivo que coincida con el nombre base de la primera URL proporcionada y usar esa copia local
si el hash coincide.
Bazel usa esta técnica para realizar un arranque sin conexión desde la distribución
artefacto.
Para ello, recopila todos los recursos
dependencias
en un entorno
distdir_tar
Sin embargo, bazel permite la ejecución de comandos arbitrarios en las reglas del repositorio. sin saber si llaman a la red. Por lo tanto, Bazel no tiene opción para que las compilaciones sean completamente sin conexión. Por lo tanto, probar si una compilación funciona correctamente el uso sin conexión requiere el bloqueo externo de la red, como lo hace Bazel en su una prueba de arranque.
Prácticas recomendadas
Reglas del repositorio
Por lo general, una regla de repositorio debe ser responsable de lo siguiente:
- Detectar la configuración del sistema y escribirla en archivos.
- Buscar recursos en otras partes del sistema.
- Se están descargando recursos a partir de URLs.
- Generar o vincular symlink archivos BUILD en el directorio del repositorio externo
Evita usar repository_ctx.execute
cuando sea posible. Por ejemplo, cuando usas un código C++ que no es de Bazel
que tiene una compilación con Make, es preferible usar repository_ctx.download()
y, luego,
escribe un archivo BUILD que lo compile, en lugar de ejecutar ctx.execute(["make"])
.
Prefiero http_archive
en lugar de git_repository
y
new_git_repository
Estos son los motivos:
- Las reglas del repositorio de Git dependen del sistema
git(1)
, mientras que el descargador HTTP se compila a Bazel y no tiene dependencias de sistema. http_archive
admite una lista deurls
como duplicaciones, ygit_repository
solo admite una. un soloremote
.http_archive
funciona con la caché del repositorio, pero nogit_repository
Consulta #5116 para obtener más información.
No uses bind()
. Consulta "Considera quitar
vincular durante mucho tiempo
debate sobre sus problemas y alternativas.