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 corto.
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 se deben definir antes de usarlas. Sin embargo, la mayoría de los archivos BUILD
solo contienen declaraciones de reglas de compilación, y el orden relativo de estas instrucciones es irrelevante. Lo único que importa es qué reglas se declararon y con qué valores cuando se completa la evaluación del paquete.
Cuando se ejecuta una función de regla de compilación, como cc_library
, se crea un nuevo destino en el gráfico. Más adelante, se puede hacer referencia a este destino con una etiqueta.
En los 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, instrucciones for
ni instrucciones 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, no se permiten los argumentos *args
y **kwargs
en los archivos BUILD
. En su lugar, enumera todos los argumentos de forma explícita.
Es fundamental destacar que los programas en Starlark no pueden realizar E/S arbitrarias. Esta invariante hace que la interpretación de los archivos BUILD
sea hermética, es decir, que dependa solo de un conjunto conocido de entradas, lo que es fundamental 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.
Dado que los archivos BUILD
deben actualizarse cada vez que cambian las dependencias del código subyacente, suelen mantenerlos varias personas de un equipo. Los autores de archivos BUILD
deben agregar comentarios de forma abundante para documentar el rol de cada destino de compilación, ya sea que esté destinado al uso público o no, 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 instrucción 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 usando argumentos adicionales en la llamada a load
. Los argumentos deben ser literales de cadena (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 con respecto al paquete (no al directorio) que contiene el archivo bzl
actual. Las etiquetas relativas en las instrucciones load
deben usar un :
inicial.
load
también admite alias, por lo que puedes asignar diferentes nombres a los símbolos importados.
load("//foo/bar:file.bzl", library_alias = "some_library")
Puedes definir varios alias en una misma instrucción load
. Además, la lista de argumentos puede contener tanto alias como 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 se presentan en familias, agrupadas por idioma. Por ejemplo, cc_binary
, cc_library
y cc_test
son las reglas de compilación para los archivos binarios, las bibliotecas y las pruebas de C++, respectivamente. Otros lenguajes usan el mismo esquema de nombres, con un prefijo diferente, como java_*
para Java. Algunas de estas funciones se documentan en la Enciclopedia de compilación, pero cualquier persona puede crear reglas nuevas.
Las reglas de
*_binary
compilan programas ejecutables en un lenguaje determinado. Después de una compilación, el ejecutable residirá en el árbol de salida binaria de la herramienta de compilación con el nombre correspondiente a la etiqueta de la regla, por lo que//my:program
aparecerá en (por ejemplo)$(BINDIR)/my/program
.En algunos lenguajes, estas reglas también crean un directorio de runfiles que contiene todos los archivos mencionados en un atributo
data
perteneciente a la regla, o cualquier regla en su cierre transitivo de dependencias. Este conjunto de archivos se recopila en un solo lugar para facilitar la implementación en producción.Las reglas
*_test
son una especialización de una regla*_binary
y se utilizan para las pruebas automatizadas. Las pruebas son simplemente programas que devuelven cero si se ejecutan correctamente.Al igual que los archivos binarios, las pruebas también tienen árboles de archivos ejecutables, y los archivos que se encuentran debajo son los únicos que una prueba puede abrir de forma legítima en el tiempo de ejecución. Por ejemplo, un programa
cc_test(name='x', data=['//foo:bar'])
puede 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 todas son equivalentes a usar la variable de entorno directamente). Si no se observa la regla, la prueba fallará cuando se ejecute en un host de prueba remoto.Las reglas de
*_library
especifican módulos compilados por separado en el lenguaje de programación determinado. Las bibliotecas pueden depender de otras bibliotecas, y los archivos binarios y las pruebas pueden depender de las bibliotecas, con el comportamiento de compilación independiente esperado.
Etiquetas | Dependencias |