Descripción general de las dependencias externas

Informar un problema . Ver fuente . . Por la noche · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel admite dependencias externas, archivos de origen (de texto y binarios) usados de tu compilación que no sean de tu lugar de trabajo. Por ejemplo, podrían ser una de reglas alojadas en un repositorio de GitHub, un artefacto de Maven o un directorio en tu fuera de tu espacio de trabajo actual.

A partir de Bazel 6.0, hay dos formas de administrar dependencias externas con Bazel: el sistema WORKSPACE tradicional y centrado en el repositorio. el nuevo sistema MODULE.bazel centrado en el módulo (con nombre interno Bzlmod, y habilitado con la marca --enable_bzlmod). Ambos sistemas se pueden usar pero Bzlmod reemplazará el sistema WORKSPACE en el futuro de Bazel consulta la guía de migración de Bzlmod para saber cómo migrar.

En este documento, se explican los conceptos en torno a la administración de dependencias externas. en Bazel, antes de entrar en más detalles sobre los dos sistemas en orden.

Conceptos

Repositorio

Un árbol de directorios con un archivo de marcador de límite en la raíz que contenga el código fuente que se pueden usar en una compilación de Bazel. A menudo se abrevia como repo.

Un archivo de marcador de límite del repositorio puede ser MODULE.bazel (lo que indica que este repositorio representa un módulo de Bazel), REPO.bazel (consulta a continuación) o en contextos heredados, WORKSPACE o WORKSPACE.bazel. Cualquier archivo de marcador de límite del repositorio significará los límites de un repositorio; varios archivos de este tipo pueden coexistir en un .

Repositorio principal

El repositorio en el que se ejecuta el comando de Bazel actual.

La raíz del repositorio principal también se conoce como raíz del lugar de trabajo.

Lugar de trabajo

El entorno que comparten todos los comandos de Bazel se ejecuta en el mismo repositorio principal. Integra que abarca el repositorio principal y el conjunto de repositorios externos definidos.

Históricamente, los conceptos de “repositorio” y “espacio de trabajo” han sido combinadas; el término “espacio de trabajo” se suele usar para referirse a los principales repositorio y, a veces, incluso se usa como sinónimo de "repositorio".

Nombre del repositorio canónico

El nombre canónico con el que se puede acceder a un repositorio. En el contexto de un cada repositorio tiene un solo nombre canónico. Un destino dentro de un repositorio cuyo nombre canónico es canonical_name se puede resolver mediante la etiqueta @@canonical_name//package:target (ten en cuenta el @ doble).

El repositorio principal siempre tiene la cadena vacía como nombre canónico.

Nombre aparente del repositorio

El nombre con el que se puede acceder a un repositorio en el contexto de otro repositorio específico. Esto puede considerarse como el "sobrenombre" del repositorio: el repo con nombre canónico michael podría tener el nombre aparente mike en el contexto del repositorio alice, pero puede tener el nombre aparente mickey en el contexto del repositorio bob En este caso, la etiqueta puede abordar un objetivo dentro de michael. @mike//package:target en el contexto de alice (ten en cuenta el único @).

Por el contrario, esto se puede entender como una asignación de repositorio: cada repositorio mantiene una asignación del "nombre aparente del repo" a un "nombre del repositorio canónico".

Regla del repositorio

Un esquema para las definiciones de repositorios que le indica a Bazel cómo materializar una en un repositorio de confianza. Por ejemplo, podría ser "descarga un archivo ZIP de una URL determinada “extraer” o “obtener un determinado artefacto de Maven y hacer que esté disponible como java_import target” o “symlink un directorio local”. Todos los repo definida llamando a una regla de repositorio con una cantidad apropiada de argumentos.

Consulta Reglas del repositorio para obtener más información sobre cómo escribir. las reglas de tu repositorio.

Sin duda, las reglas de repo más comunes son http_archive, que descarga un archivo de una URL y la extrae. local_repository, que vincula un symlink a que ya es un repositorio de Bazel.

Recupera un repositorio

La acción de hacer que un repositorio esté disponible en el disco local ejecutando su repo. Los repositorios definidos en un lugar de trabajo no están disponibles en el disco local. antes de que se recuperen.

Por lo general, Bazel solo recupera un repo cuando necesita algo del repo. y aún no se recuperó el repo. Si ya se recuperó el repo anteriormente, Bazel solo lo vuelve a recuperar si su definición cambió.

El comando fetch se puede usar para iniciar una carga previa de un repositorio. destino o todos los repositorios necesarios para realizar cualquier compilación. Esta función habilita compilaciones sin conexión con la opción --nofetch.

La opción --fetch sirve para administrar el acceso a la red. Su valor predeterminado es verdadero. Sin embargo, cuando se establece como falsa (--nofetch), el comando usará cualquier de la dependencia y, si no existe ninguna, el comando generará falla.

Consulta las opciones de recuperación para obtener más información para controlar la recuperación de datos.

Diseño de directorio

Después de que se recupere, podrás encontrar el repositorio en el subdirectorio external, en el base de salida, debajo de su nombre canónico.

Puedes ejecutar el siguiente comando para ver el contenido del repo con el nombre canónico canonical_name:

ls $(bazel info output_base)/external/ canonical_name 

Archivo REPO.bazel

El archivo REPO.bazel se usa para marcar el límite superior del árbol de directorios. que constituye un repositorio. No necesita contener nada para funcionar como repositorio. archivo de límite; pero también se puede usar para especificar algunos atributos comunes para todos los objetivos de compilación dentro del repositorio.

La sintaxis de un archivo REPO.bazel es similar a la de los archivos BUILD, excepto que no Se admiten sentencias load, y se aplica una sola función, repo() disponibles. repo() toma los mismos argumentos que package(). función en archivos BUILD; mientras que package() especifica atributos comunes para todos los objetivos de compilación dentro del paquete, repo() del mismo modo, lo hace para todos los objetivos de compilación dentro del repositorio.

Por ejemplo, puedes especificar una licencia común para todos los destinos de tu repositorio. Para ello, haz lo siguiente: tener el siguiente archivo REPO.bazel:

repo(
    default_package_metadata = ["//:my_license"],
)

Cómo administrar dependencias externas con Bzlmod

Bzlmod, el nuevo subsistema de dependencia externa, no funciona directamente con repo. definiciones En su lugar, compila un gráfico de dependencia a partir de módulos, ejecuta extensions en la parte superior del gráfico y define los repositorios según corresponda.

Un módulo de Bazel es un proyecto de Bazel que puede tener varios y cada una publica metadatos sobre otros módulos de los que depende . Un módulo debe tener un archivo MODULE.bazel en la raíz del repositorio, junto al archivo WORKSPACE. Este archivo es el manifiesto del módulo, que declara su nombre la versión y la lista de dependencias, entre otros datos. La siguiente es una ejemplo:

module(name = "my-module", version = "1.0")

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

Un módulo solo debe enumerar sus dependencias directas, que Bzlmod busca en un Registro de Bazel: De forma predeterminada, se llama Bazel Central Registro. El registro proporciona la de las dependencias MODULE.bazel, que permiten que Bazel descubra toda la gráfico de dependencia transitivo antes de realizar la resolución de la versión.

Después de la resolución de versión, en la que se selecciona una versión para cada módulo, Bazel vuelve a consultar el registro para aprender a definir un repositorio para cada módulo. (en la mayoría de los casos, mediante http_archive).

Los módulos también pueden especificar datos personalizados llamados etiquetas, que se consumidas por las extensiones del módulo después de la resolución del módulo para definir repositorios adicionales. Estas extensiones tienen funciones similares a las de repo. reglas de firewall, lo que les permite realizar acciones como E/S de archivos y enviar solicitudes. Entre otras cosas, permiten que Bazel interactúe con otros paquetes de los sistemas de administración, a la vez que respeta el gráfico de dependencias creado a partir de Bazel módulos.

Define repositorios con WORKSPACE

Históricamente, se pueden administrar dependencias externas definiendo repositorios en el Archivo WORKSPACE (o WORKSPACE.bazel). Este archivo tiene una sintaxis similar a BUILD y emplean reglas de repositorio en lugar de reglas de compilación.

El siguiente fragmento es un ejemplo de cómo usar la regla del repositorio http_archive en el Archivo WORKSPACE:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "foo",
    urls = ["https://example.com/foo.zip"],
    sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)

El fragmento define un repositorio cuyo nombre canónico es foo. En WORKSPACE de forma predeterminada, el nombre canónico de un repositorio también es su nombre aparente para todos los demás repos.

Consulta la lista completa de funciones disponibles en WORKSPACE.

Deficiencias del sistema de WORKSPACE

Durante los años desde que se introdujo el sistema WORKSPACE, los usuarios informaron muchas dificultades, como las siguientes:

  • Bazel no evalúa los archivos WORKSPACE de ninguna dependencia, por lo que las dependencias transitivas deben definirse en el archivo WORKSPACE de la instancia repo, además de las dependencias directas.
  • Para solucionar esto, los proyectos adoptaron el estándar "deps.bzl" en el que definen una macro que, a su vez, define varios repositorios y les piden a los usuarios llamarán a esta macro en sus archivos WORKSPACE.
    • Esto tiene sus propios problemas: las macros no pueden load otros archivos .bzl, por lo que estos proyectos tienen que definir sus dependencias transitivas en este “deps” o haz que el usuario llame a varias “deps” en capas o usar las macros.
    • Bazel evalúa el archivo WORKSPACE de forma secuencial. Además: las dependencias se especifican mediante http_archive con URLs, sin ninguna información de la versión. Esto significa que no hay una forma confiable de realizar resolución de la versión en el caso de dependencias de diamante (A depende de B y C; B y C dependen de diferentes versiones de D).

Debido a las deficiencias de WORKSPACE, Bzlmod reemplazará la versión heredada WORKSPACE en versiones futuras de Bazel. Lee el artículo sobre la migración a Bzlmod sobre cómo migrar a Bzlmod.