Reglas
alias
alias(name, actual, compatible_with, deprecation, features, restricted_to, tags, target_compatible_with, testonly, visibility)
La regla alias crea otro nombre con el que se puede hacer referencia a una regla.
El alias solo funciona para los destinos "normales". En particular, package_group y test_suite no pueden tener alias.
La regla de alias tiene su propia declaración de visibilidad. En todos los demás aspectos, se comporta como la regla a la que hace referencia (p.ej., se ignora testonly en el alias; en su lugar, se usa el atributo testonly de la regla a la que se hace referencia) con algunas excepciones menores:
-
Las pruebas no se ejecutan si se menciona su alias en la línea de comandos. Para definir un alias que ejecute la prueba a la que se hace referencia, usa una regla
test_suitecon un solo destino en su atributotests. -
Cuando se definen grupos de entornos, no se admiten los alias para las reglas de
environment. Tampoco se admiten en la opción de línea de comandos--target_environment.
Ejemplos
filegroup(
name = "data",
srcs = ["data.txt"],
)
alias(
name = "other",
actual = ":data",
)
Argumentos
| Atributos | |
|---|---|
name |
Es un nombre único para este destino. |
actual
|
|
config_setting
config_setting(name, constraint_values, define_values, deprecation, distribs, features, flag_values, licenses, tags, testonly, values, visibility)
Coincide con un estado de configuración esperado (expresado como marcas de compilación o restricciones de plataforma) con el propósito de activar atributos configurables. Consulta select para obtener información sobre cómo consumir esta regla y Configurable attributes para obtener una descripción general de la función general.
Ejemplos
La siguiente coincidencia se aplica a cualquier compilación que establezca --compilation_mode=opt o -c opt (ya sea de forma explícita en la línea de comandos o de forma implícita desde los archivos .bazelrc):
config_setting(
name = "simple",
values = {"compilation_mode": "opt"}
)
El siguiente ejemplo coincide con cualquier compilación que se oriente a ARM y aplique la definición personalizada FOO=bar (por ejemplo, bazel build --cpu=arm --define FOO=bar ...):
config_setting(
name = "two_conditions",
values = {
"cpu": "arm",
"define": "FOO=bar"
}
)
La siguiente coincidencia se aplica a cualquier compilación que establezca la marca definida por el usuario
--//custom_flags:foo=1 (ya sea de forma explícita en la línea de comandos o de forma implícita desde los archivos .bazelrc):
config_setting(
name = "my_custom_flag_is_set",
flag_values = { "//custom_flags:foo": "1" },
)
La siguiente coincidencia se aplica a cualquier compilación que tenga como objetivo una plataforma con una arquitectura x86_64 y la versión 2.25 de glibc, suponiendo la existencia de un constraint_value con la etiqueta //example:glibc_2_25. Ten en cuenta que una plataforma sigue coincidiendo si define valores de restricción adicionales más allá de estos dos.
config_setting(
name = "64bit_glibc_2_25",
constraint_values = [
"@platforms//cpu:x86_64",
"//example:glibc_2_25",
]
)
config_setting no coincide con las marcas de línea de comandos de nivel superior, es posible que coincida con
algunos destinos de compilación.
Notas
- Consulta select para saber qué sucede cuando varios
config_settingcoinciden con el estado de configuración actual. - En el caso de las marcas que admiten formas abreviadas (p. ej.,
--compilation_modeen lugar de-c), las definiciones devaluesdeben usar la forma completa. Estas invocaciones coinciden automáticamente con cualquiera de las dos formas. -
Si una marca toma varios valores (como
--copt=-Da --copt=-Dbo una marca de Starlark de tipo lista),values = { "flag": "a" }coincide si"a"está presente en cualquier lugar de la lista real.values = { "myflag": "a,b" }funciona de la misma manera: coincide con--myflag=a --myflag=b,--myflag=a --myflag=b --myflag=c,--myflag=a,by--myflag=c,b,a. La semántica exacta varía entre las marcas. Por ejemplo,--coptno admite varios valores en la misma instancia:--copt=a,bproduce["a,b"], mientras que--copt=a --copt=bproduce["a", "b"](por lo quevalues = { "copt": "a,b" }coincide con el primero, pero no con el segundo). Pero--ios_multi_cpus(para reglas de Apple) sí:-ios_multi_cpus=a,byios_multi_cpus=a --ios_multi_cpus=bproducen["a", "b"]. Verifica las definiciones de las marcas y prueba tus condiciones con cuidado para verificar las expectativas exactas. - Si necesitas definir condiciones que no se modelan con marcas de compilación integradas, usa
marcas definidas por Starlark. También puedes usar
--define, pero ofrece menos compatibilidad y no se recomienda. Consulta aquí para obtener más información. - Evita repetir definiciones de
config_settingidénticas en diferentes paquetes. En su lugar, haz referencia a unconfig_settingcomún definido en un paquete canónico. values,define_valuesyconstraint_valuesse pueden usar en cualquier combinación en el mismoconfig_setting, pero se debe establecer al menos uno para cualquierconfig_settingdeterminado.
Argumentos
| Atributos | |
|---|---|
name |
Es un nombre único para este destino. |
constraint_values
|
constraint_values que la plataforma de destino debe especificar para que coincida con este config_setting. (Aquí no se considera la plataforma de ejecución). Se ignoran los valores de restricción adicionales que tiene la plataforma. Consulta
Atributos de compilación configurables para obtener más detalles.
En el caso en que dos |
define_values
|
values, pero específicamente para el parámetro --define.
Esto significa lo siguiente:
config_setting(
name = "a_and_b",
values = {
"define": "a=1",
"define": "b=2",
})
no funciona porque la misma clave (
config_setting(
name = "a_and_b",
define_values = {
"a": "1",
"b": "2",
})
coincide correctamente con
|
flag_values
|
values, pero para
indicadores de compilación definidos por el usuario.
Este es un atributo distinto porque las marcas definidas por el usuario se referencian como etiquetas, mientras que las marcas integradas se referencian como cadenas arbitrarias. |
values
|
Esta regla hereda la configuración del destino configurado que la referencia en una declaración Para mayor comodidad, los valores de configuración se especifican como marcas de compilación (sin el Si no se establece una marca de forma explícita en la línea de comandos, se usa su valor predeterminado.
Si una clave aparece varias veces en el diccionario, solo se usa la última instancia.
Si una clave hace referencia a una marca que se puede establecer varias veces en la línea de comandos (p.ej.,
|
filegroup
filegroup(name, srcs, data, compatible_with, deprecation, distribs, features, licenses, output_group, restricted_to, tags, target_compatible_with, testonly, visibility)
Usa filegroup para darle un nombre conveniente a una colección de destinos.
Luego, se puede hacer referencia a ellas desde otras reglas.
Se recomienda usar filegroup en lugar de hacer referencia a directorios directamente.
Esta última opción no es confiable, ya que el sistema de compilación no tiene conocimiento completo de todos los archivos que se encuentran debajo del directorio, por lo que es posible que no vuelva a compilar cuando cambien estos archivos. Cuando se combina con glob, filegroup puede garantizar que el sistema de compilación conozca explícitamente todos los archivos.
Ejemplos
Para crear un filegroup que consta de dos archivos fuente, haz lo siguiente:
filegroup(
name = "mygroup",
srcs = [
"a_file.txt",
"some/subdirectory/another_file.txt",
],
)
O bien, usa glob para analizar un directorio de datos de prueba:
filegroup(
name = "exported_testdata",
srcs = glob([
"testdata/*.dat",
"testdata/logs/**/*.log",
]),
)
Para usar estas definiciones, haz referencia a filegroup con una etiqueta de cualquier regla:
cc_library(
name = "my_library",
srcs = ["foo.cc"],
data = [
"//my_package:exported_testdata",
"//my_package:mygroup",
],
)
Argumentos
| Atributos | |
|---|---|
name |
Es un nombre único para este destino. |
srcs
|
Es común usar el resultado de una expresión glob para el valor del atributo |
data
|
Los destinos nombrados en el atributo |
output_group
|
Un "grupo de salida" es una categoría de artefactos de salida de un destino, especificada en la implementación de esa regla. |
genquery
genquery(name, deps, data, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, expression, features, licenses, opts, restricted_to, scope, strict, tags, target_compatible_with, testonly, visibility)
genquery() ejecuta una consulta especificada en el lenguaje de consultas de Blaze y vuelca el resultado en un archivo.
Para mantener la coherencia de la compilación, la consulta solo puede visitar el cierre transitivo de los destinos especificados en el atributo scope. Las consultas que incumplan esta regla fallarán durante la ejecución si strict no se especifica o es verdadero (si strict es falso, los objetivos fuera del alcance simplemente se omitirán con una advertencia). La forma más sencilla de asegurarse de que esto no suceda es mencionar las mismas etiquetas en el alcance que en la expresión de búsqueda.
La única diferencia entre las consultas permitidas aquí y en la línea de comandos es que no se permiten las consultas que contienen especificaciones de destino con comodines (p.ej., //pkg:* o //pkg:all).
Esto se debe a dos motivos: primero, porque genquery debe especificar un alcance para evitar que los destinos fuera del cierre transitivo de la consulta influyan en su resultado y, segundo, porque los archivos BUILD no admiten dependencias de comodín (p.ej., deps=["//a/..."] no está permitido).
El resultado de la genquery se ordena con --order_output=full para garantizar un resultado determinístico.
El nombre del archivo de salida es el nombre de la regla.
Ejemplos
En este ejemplo, se escribe la lista de etiquetas en el cierre transitivo del destino especificado en un archivo.
genquery(
name = "kiwi-deps",
expression = "deps(//kiwi:kiwi_lib)",
scope = ["//kiwi:kiwi_lib"],
)
Argumentos
| Atributos | |
|---|---|
name |
Es un nombre único para este destino. |
expression
|
:b en este atributo del archivo a/BUILD hará referencia al destino //:b.
|
opts
|
bazel query. Algunas opciones de búsqueda no se permiten aquí: --keep_going, --query_file, --universe_scope, --order_results y --order_output. Las opciones que no se especifican aquí tendrán sus valores predeterminados, al igual que en la línea de comandos de bazel query.
|
scope
|
|
strict
|
|
genrule
genrule(name, srcs, outs, cmd, cmd_bash, cmd_bat, cmd_ps, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, exec_tools, executable, features, licenses, local, message, output_licenses, output_to_bindir, restricted_to, tags, target_compatible_with, testonly, toolchains, tools, visibility)
Un genrule genera uno o más archivos con un comando de Bash definido por el usuario.
Las genrules son reglas de compilación genéricas que puedes usar si no hay una regla específica para la tarea.
Por ejemplo, podrías ejecutar un comando de Bash de una sola línea. Sin embargo, si necesitas compilar archivos C++, usa las reglas cc_* existentes, ya que todo el trabajo pesado ya se hizo por ti.
No uses genrule para ejecutar pruebas. Existen dispensaciones especiales para las pruebas y los resultados de las pruebas, incluidas las políticas de almacenamiento en caché y las variables de entorno. Por lo general, las pruebas deben ejecutarse después de que se complete la compilación y en la arquitectura de destino, mientras que las reglas de generación se ejecutan durante la compilación y en la arquitectura del host (las dos pueden ser diferentes). Si necesitas una regla de prueba de propósito general, usa sh_test.
Consideraciones sobre la compilación cruzada
Consulta el manual del usuario para obtener más información sobre la compilación cruzada.
Si bien las genrules se ejecutan durante una compilación, sus resultados a menudo se usan después de la compilación, para la implementación o las pruebas. Considera el ejemplo de compilar código C para un microcontrolador: el compilador acepta archivos fuente C y genera código que se ejecuta en un microcontrolador. Obviamente, el código generado no se puede ejecutar en la CPU que se usó para compilarlo, pero el compilador de C (si se compiló desde la fuente) sí debe hacerlo.
El sistema de compilación usa la configuración del host para describir las máquinas en las que se ejecuta la compilación y la configuración de destino para describir las máquinas en las que se supone que se ejecutará el resultado de la compilación. Proporciona opciones para configurar cada uno de estos y segrega los archivos correspondientes en directorios separados para evitar conflictos.
En el caso de las genrules, el sistema de compilación garantiza que las dependencias se compilen de forma adecuada:
Los srcs se compilan (si es necesario) para la configuración del destino.
Los tools se compilan para la configuración del host, y la salida se considera para la configuración del destino. También proporciona
variables de "Make" que los comandos de genrule pueden pasar a las herramientas correspondientes.
Es intencional que genrule no defina ningún atributo deps: otras reglas integradas usan metainformación dependiente del lenguaje que se pasa entre las reglas para determinar automáticamente cómo controlar las reglas dependientes, pero este nivel de automatización no es posible para las genrules. Las reglas de generación funcionan puramente a nivel de archivos y archivos ejecutables.
Casos especiales
Compilación host-host: En algunos casos, el sistema de compilación debe ejecutar genrules de modo que el resultado también se pueda ejecutar durante la compilación. Si, por ejemplo, una regla genrule compila un compilador personalizado que luego usa otra regla genrule, la primera debe generar su resultado para la configuración del host, ya que es allí donde se ejecutará el compilador en la otra regla genrule. En este caso, el sistema de compilación hace lo correcto automáticamente: compila srcs y outs de la primera regla genrule para la configuración del host en lugar de la configuración del destino. Consulta el manual del usuario para obtener más información.
JDK y herramientas de C++: Para usar una herramienta del JDK o del conjunto de compiladores de C++, el sistema de compilación proporciona un conjunto de variables para usar. Consulta la variable"Make" para obtener más detalles.
Entorno de Genrule
El comando genrule se ejecuta con un shell de Bash que está configurado para fallar cuando falla un comando o una canalización, con set -e -o pipefail.
La herramienta de compilación ejecuta el comando de Bash en un entorno de proceso saneado que solo define variables principales, como PATH, PWD, TMPDIR y algunas otras.
Para garantizar que las compilaciones sean reproducibles, la mayoría de las variables definidas en el entorno de shell del usuario no se pasan al comando de genrule. Sin embargo, Bazel (pero no Blaze) pasa el valor de la variable de entorno PATH del usuario.
Cualquier cambio en el valor de PATH hará que Bazel vuelva a ejecutar el comando en la próxima compilación.
Un comando de genrule no debe acceder a la red, excepto para conectar procesos que sean secundarios del comando en sí, aunque esto no se aplica actualmente.
El sistema de compilación borra automáticamente los archivos de salida existentes, pero crea los directorios principales necesarios antes de ejecutar una regla genrule. También quita los archivos de salida en caso de falla.
Asesoramiento general
- Asegúrate de que las herramientas que ejecuta una regla genrule sean determinísticas y herméticas. No deben escribir marcas de tiempo en su salida y deben usar un orden estable para los conjuntos y los mapas, así como escribir solo rutas de acceso relativas a los archivos en la salida, no rutas de acceso absolutas. No seguir esta regla generará un comportamiento inesperado de la compilación (Bazel no recompilará una regla genrule que creías que recompilaría) y degradará el rendimiento de la caché.
- Usa
$(location)de forma extensiva para las salidas, las herramientas y las fuentes. Debido a la segregación de los archivos de salida para diferentes configuraciones, las reglas de generación no pueden depender de rutas codificadas o absolutas. - Escribe una macro de Starlark común en caso de que se usen genrules iguales o muy similares en varios lugares. Si la regla genrule es compleja, considera implementarla en una secuencia de comandos o como una regla de Starlark. Esto mejora la legibilidad y la capacidad de prueba.
- Asegúrate de que el código de salida indique correctamente si la regla genrule se ejecutó correctamente o no.
- No escribas mensajes informativos en stdout o stderr. Si bien es útil para la depuración, esto puede convertirse fácilmente en ruido. Una genrule exitosa debería ser silenciosa. Por otro lado, una genrule que falla debe emitir buenos mensajes de error.
$$evaluates to a$, a literal dollar-sign, so in order to invoke a shell command containing dollar-signs such asls $(dirname $x), one must escape it thus:ls $$(dirname $$x).- Evita crear vínculos simbólicos y directorios. Bazel no copia la estructura de directorios o vínculos simbólicos que crean las genrules, y su verificación de dependencias de directorios no es sólida.
- Cuando hagas referencia a la regla genrule en otras reglas, puedes usar la etiqueta de la regla genrule o las etiquetas de los archivos de salida individuales. A veces, un enfoque es más legible y, otras veces, el otro: hacer referencia a los resultados por nombre en el
srcsde una regla de consumo evitará la selección no intencional de otros resultados de la genrule, pero puede ser tedioso si la genrule produce muchos resultados.
Ejemplos
En este ejemplo, se genera foo.h. No hay fuentes, ya que el comando no toma ninguna entrada. El "ejecutable" que ejecuta el comando es una secuencia de comandos de Perl en el mismo paquete que genrule.
genrule(
name = "foo",
srcs = [],
outs = ["foo.h"],
cmd = "./$(location create_foo.pl) > \"$@\"",
tools = ["create_foo.pl"],
)
En el siguiente ejemplo, se muestra cómo usar un filegroup
y los resultados de otro genrule. Ten en cuenta que también funcionaría usar $(SRCS) en lugar de directivas $(location) explícitas. En este ejemplo, se usa la última opción para fines de demostración.
genrule(
name = "concat_all_files",
srcs = [
"//some:files", # a filegroup with multiple files in it ==> $(locations)
"//other:gen", # a genrule with a single output ==> $(location)
],
outs = ["concatenated.txt"],
cmd = "cat $(locations //some:files) $(location //other:gen) > $@",
)
Argumentos
| Atributos | |
|---|---|
name |
Es un nombre único para este destino. Puedes hacer referencia a esta regla por su nombre en la sección srcs o deps de otras reglas BUILD. Si la regla genera archivos fuente, debes usar el atributo srcs.
|
srcs
|
Este atributo no es adecuado para enumerar las herramientas que ejecuta
El sistema de compilación garantiza que estos requisitos previos se compilen antes de ejecutar el comando genrule. Se compilan con la misma configuración que la solicitud de compilación original. Los nombres de los archivos de estos requisitos previos están disponibles para el comando como una lista separada por espacios en |
outs
|
Los archivos de salida no deben cruzar los límites del paquete. Los nombres de los archivos de salida se interpretan como relativos al paquete.
Si se configura la marca
Se espera que el comando genrule cree cada archivo de salida en una ubicación predeterminada.
La ubicación está disponible en |
cmd
|
$(location)
y "Make"
cmd_bash, cmd_ps y cmd_bat,
si ninguno de ellos es aplicable.
Si la longitud de la línea de comandos supera el límite de la plataforma (64 K en Linux/macOS y 8 K en Windows), genrule escribirá el comando en una secuencia de comandos y ejecutará esa secuencia para solucionar el problema. Esto se aplica a todos los atributos de cmd ( |
cmd_bash
|
Este atributo tiene mayor prioridad que |
cmd_bat
|
Este atributo tiene mayor prioridad que
|
cmd_ps
|
Este atributo tiene mayor prioridad que
Para que PowerShell sea más fácil de usar y menos propenso a errores, ejecutamos los siguientes comandos para configurar el entorno antes de ejecutar el comando de PowerShell en genrule.
|
exec_tools
|
tools, excepto que estas dependencias se configurarán para la plataforma de ejecución de la regla en lugar de la configuración del host.
Esto significa que las dependencias en exec_tools no están sujetas a las mismas limitaciones que las dependencias en tools. En particular, no se les exige que usen la configuración del host para sus propias dependencias transitivas. Consulta tools para obtener más detalles.
El equipo de Blaze está migrando todos los usos de |
executable
|
Si se establece esta marca como verdadera, significa que el resultado es un archivo ejecutable y se puede ejecutar con el comando No se admite la declaración de dependencias de datos para el ejecutable generado. |
local
|
Si se establece como verdadero, esta opción obliga a que este
Esto equivale a proporcionar "local" como etiqueta ( |
message
|
Es un mensaje de progreso que se imprimirá a medida que se ejecute este paso de compilación. De forma predeterminada, el mensaje es "Generando salida" (o algo igual de insípido), pero puedes proporcionar uno más específico. Usa este atributo en lugar de |
output_licenses
|
common attributes
|
output_to_bindir
|
Si se establece en True, esta opción hace que los archivos de salida se escriban en el directorio |
tools
|
El sistema de compilación garantiza que estos requisitos previos se compilen antes de ejecutar el comando genrule; se compilan con la configuración de host, ya que estas herramientas se ejecutan como parte de la compilación. La ruta de acceso de un destino
Cualquier |
test_suite
test_suite(name, compatible_with, deprecation, distribs, features, licenses, restricted_to, tags, target_compatible_with, testonly, tests, visibility)
Un test_suite define un conjunto de pruebas que se consideran "útiles" para los humanos. Esto permite que los proyectos definan conjuntos de pruebas, como "pruebas que debes ejecutar antes de la confirmación", "pruebas de estrés de nuestro proyecto" o "todas las pruebas pequeñas". El comando blaze test respeta este tipo de organización: para una invocación como blaze test //some/test:suite, Blaze primero enumera todos los destinos de prueba incluidos de forma transitiva por el destino //some/test:suite (a esto lo llamamos "expansión de test_suite"), luego Blaze compila y prueba esos destinos.
Ejemplos
Es un paquete de pruebas para ejecutar todas las pruebas pequeñas en el paquete actual.
test_suite(
name = "small_tests",
tags = ["small"],
)
Un conjunto de pruebas que ejecuta un conjunto especificado de pruebas:
test_suite(
name = "smoke_tests",
tests = [
"system_unittest",
"public_api_unittest",
],
)
Es un paquete de pruebas para ejecutar todas las pruebas del paquete actual que no son inestables.
test_suite(
name = "non_flaky_test",
tags = ["-flaky"],
)
Argumentos
| Atributos | |
|---|---|
name |
Es un nombre único para este destino. |
tags
|
Las etiquetas que comienzan con un carácter "-" se consideran etiquetas negativas. El carácter "-" precedente no se considera parte de la etiqueta, por lo que una etiqueta de conjunto de pruebas "-small" coincide con el tamaño "small" de una prueba. Todas las demás etiquetas se consideran positivas. De manera opcional, para que las etiquetas positivas sean más explícitas, también pueden comenzar con el carácter "+", que no se evaluará como parte del texto de la etiqueta. Simplemente, facilita la lectura de la distinción entre positivo y negativo. En el conjunto de pruebas, solo se incluirán las reglas de prueba que coincidan con todas las etiquetas positivas y ninguna de las etiquetas negativas. Ten en cuenta que esto no significa que se omita la verificación de errores para las dependencias en las pruebas que se filtran. Las dependencias en las pruebas omitidas aún deben ser válidas (p. ej., no deben estar bloqueadas por restricciones de visibilidad).
La palabra clave de la etiqueta
Ten en cuenta que el
Si necesitas un |
tests
|
Aquí se acepta cualquier
Si el atributo |