Archivos BUILD

Denuncia un problema Ver fuente Nightly · 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

En las secciones anteriores, se describieron los paquetes, los destinos y las etiquetas, y el gráfico de dependencias de compilación de forma abstracta. En esta sección, se describe la sintaxis concreta que se usa para definir un paquete.

Por definición, cada paquete contiene un archivo BUILD, que es un programa breve.

Los archivos BUILD se evalúan con un lenguaje imperativo, Starlark.

Se interpretan como una lista secuencial de instrucciones.

En general, el orden sí importa: por ejemplo, las variables deben definirse antes de que se usen. Sin embargo, la mayoría de los archivos BUILD consisten solo en declaraciones de reglas de compilación, y el orden relativo de estas declaraciones es inmaterial. Lo único que importa es qué reglas se declararon y con qué valores, según el momento en que se completa la evaluación del paquete.

Cuando se ejecuta una función de regla de compilación, como cc_library, se crea un objetivo nuevo en el gráfico. Más adelante, se puede hacer referencia a este destino con una etiqueta.

En archivos BUILD simples, las declaraciones de reglas se pueden reordenar libremente sin cambiar el comportamiento.

Para fomentar una separación clara entre el código y los datos, los archivos BUILD no pueden contener definiciones de funciones, sentencias for ni sentencias if (pero se permiten las comprensiones de listas y las expresiones if). En su lugar, las funciones se pueden declarar en archivos .bzl. Además, los argumentos *args y **kwargs no se permiten en los archivos BUILD. En su lugar, enumera todos los argumentos de forma explícita.

Es fundamental que los programas en Starlark no puedan realizar E/S arbitrarias. Esta invarianza hace que la interpretación de los archivos BUILD sea hermética, ya que depende solo de un conjunto conocido de entradas, lo que es esencial para garantizar que las compilaciones sean reproducibles. Para obtener más información, consulta Hermeticity.

Los archivos BUILD deben escribirse solo con caracteres ASCII, aunque, técnicamente, se interpretan con el conjunto de caracteres Latin-1.

Debido a que los archivos BUILD deben actualizarse cada vez que cambian las dependencias del código subyacente, varias personas en un equipo suelen mantenerlos. Los autores de archivos BUILD deben hacer comentarios de forma generosa para documentar el rol de cada objetivo de compilación, ya sea que esté destinado o no para uso público, y para documentar el rol del paquete en sí.

Cómo cargar una extensión

Las extensiones de Bazel son archivos que terminan en .bzl. Usa la sentencia load para importar un símbolo desde una extensión.

load("//foo/bar:file.bzl", "some_library")

Este código carga el archivo foo/bar/file.bzl y agrega el símbolo some_library al entorno. Se puede usar para cargar reglas, funciones o constantes nuevas (por ejemplo, una cadena o una lista). Se pueden importar varios símbolos con argumentos adicionales a la llamada a load. Los argumentos deben ser cadenas literales (sin variables) y las sentencias load deben aparecer en el nivel superior; no pueden estar en el cuerpo de una función.

El primer argumento de load es una etiqueta que identifica un archivo .bzl. Si es una etiqueta relativa, se resuelve en relación con el paquete (no el directorio) que contiene el archivo bzl actual. Las etiquetas relativas en las sentencias load deben usar un : inicial.

load también admite alias, por lo que puedes asignar nombres diferentes a los símbolos importados.

load("//foo/bar:file.bzl", library_alias = "some_library")

Puedes definir varios alias dentro de una sola sentencia load. Además, la lista de argumentos puede contener alias y nombres de símbolos normales. El siguiente ejemplo es perfectamente legal (ten en cuenta cuándo usar comillas).

load(":my_rules.bzl", "some_rule", nice_alias = "some_other_rule")

En un archivo .bzl, los símbolos que comienzan con _ no se exportan y no se pueden cargar desde otro archivo.

Puedes usar la visibilidad de carga para restringir quién puede cargar un archivo .bzl.

Tipos de reglas de compilación

La mayoría de las reglas de compilación vienen en familias, agrupadas por lenguaje. Por ejemplo, cc_binary, cc_library y cc_test son las reglas de compilación para objetos binarios, bibliotecas y pruebas de C++, respectivamente. Otros lenguajes usan el mismo esquema de nombres, con un prefijo diferente, como java_* para Java. Algunas de estas funciones están documentadas en la Enciclopedia de compilación, pero cualquiera puede crear reglas nuevas.

  • Las reglas *_binary compilan programas ejecutables en un lenguaje determinado. Después de una compilación, el ejecutable residirá en el árbol de salidas binarias de las herramientas de compilación, en el nombre correspondiente de la etiqueta de la regla, por lo que //my:program aparecerá como $(BINDIR)/my/program, por ejemplo.

    En algunos lenguajes, esas reglas también crean un directorio de runfiles que contiene todos los archivos mencionados en un atributo data que pertenece a la regla, o cualquier regla en su cierre transitivo de dependencias. Este conjunto de archivos se reúne en un solo lugar para facilitar la implementación en producción.

  • Las reglas *_test son una especialización de una regla *_binary, que se usa para pruebas automatizadas. Las pruebas son simplemente programas que muestran cero cuando se realizan correctamente.

    Al igual que los objetos binarios, las pruebas también tienen árboles de archivos de ejecución, y los archivos debajo de ellas son los únicos que una prueba puede abrir legítimamente en el tiempo de ejecución. Por ejemplo, un programa cc_test(name='x', data=['//foo:bar']) podría abrir y leer $TEST_SRCDIR/workspace/foo/bar durante la ejecución. (cada lenguaje de programación tiene su propia función de utilidad para acceder al valor de $TEST_SRCDIR, pero todos son equivalentes a usar la variable de entorno directamente). Si no se cumple la regla, la prueba fallará cuando se ejecute en un host de prueba remoto.

  • Las reglas *_library especifican módulos compilados por separado en el lenguaje de programación determinado. Las bibliotecas pueden depender de otras bibliotecas, y los objetos binarios y las pruebas pueden depender de las bibliotecas, con el comportamiento esperado de compilación independiente.

Etiquetas Dependencias