Todos los destinos pertenecen exactamente a un solo paquete. El nombre del objetivo se denomina etiqueta. Cada etiqueta identifica de forma única un objetivo. Una etiqueta típica en forma canónica se ve de la siguiente manera:
@myrepo//my/app/main:app_binary
La primera parte de la etiqueta es el nombre del repositorio, @myrepo//
.
En el caso típico en el que una etiqueta hace referencia al mismo repositorio desde el que se usa, el identificador del repositorio se puede abreviar como //
.
Dentro de @myrepo
, esta etiqueta suele escribirse como
//my/app/main:app_binary
La segunda parte de la etiqueta es el nombre de paquete no calificado my/app/main
, la ruta de acceso al paquete en relación con la raíz del repositorio. Juntos, el nombre del repositorio y el nombre del paquete no calificado forman el nombre del paquete completamente calificado @myrepo//my/app/main
. Cuando la etiqueta hace referencia al mismo paquete en el que se usa, se puede omitir el nombre del paquete (y, de manera opcional, el dos puntos). Por lo tanto, dentro de @myrepo//my/app/main
, esta etiqueta se puede escribir de cualquiera de las siguientes maneras:
app_binary
:app_binary
Por convención, los dos puntos se omiten en los archivos, pero se retienen para las reglas. Sin embargo, esto no es significativo.
La parte de la etiqueta después de los dos puntos, app_binary
es el nombre del destino no calificado. Cuando coincide con el último componente de la ruta del paquete, se pueden omitir tanto él como los dos puntos. Por lo tanto, estas dos etiquetas son equivalentes:
//my/app/lib
//my/app/lib:lib
El nombre de un archivo de destino en un subdirectorio del paquete es la ruta del archivo en relación con la raíz del paquete (el directorio que contiene el archivo BUILD
). Por lo tanto, este archivo se encuentra en el subdirectorio my/app/main/testdata
del repositorio:
//my/app/main:testdata/input.txt
Las cadenas como //my/app
y @some_repo//my/app
tienen dos significados según el
contexto en el que se usan: cuando Bazel espera una etiqueta, significan
//my/app:app
y @some_repo//my/app:app
, respectivamente. Sin embargo, cuando Bazel
espera un paquete (p.ej., en las especificaciones package_group
), hace referencia al
paquete que contiene esa etiqueta.
Un error común en los archivos BUILD
es usar //my/app
para hacer referencia a un paquete o a todos los destinos de un paquete, lo que no es correcto. Recuerda que es equivalente a //my/app:app
, por lo que asigna el destino app
en el paquete my/app
del repositorio actual.
Sin embargo, se recomienda el uso de //my/app
para hacer referencia a un paquete en la especificación de archivos package_group
o .bzl
, ya que comunica claramente que el nombre del paquete es absoluto y tiene permisos de administrador en el directorio de nivel superior del lugar de trabajo.
Las etiquetas relativas no se pueden usar para hacer referencia a destinos en otros paquetes. En este caso, siempre se deben especificar el identificador del repositorio y el nombre del paquete.
Por ejemplo, si el árbol de fuentes contiene el paquete my/app
y el paquete my/app/testdata
(cada uno de estos dos directorios tiene su propio archivo BUILD
), el último paquete contendrá un archivo llamado testdepot.zip
. A continuación, se muestran dos formas (una incorrecta y una correcta) de hacer referencia a este archivo dentro de //my/app:BUILD
:
Incorrecto: testdata
es un paquete diferente, por lo que no puedes usar una ruta de acceso relativa.
testdata/testdepot.zip
Correcto: Consulta testdata
con su ruta de acceso completa.
//my/app/testdata:testdepot.zip
Las etiquetas que comienzan con @//
son referencias al repositorio principal, que seguirá funcionando incluso desde repositorios externos.
Por lo tanto, @//a/b/c
es diferente de //a/b/c
cuando se hace referencia a él desde un repositorio externo.
El primero hace referencia al repositorio principal, mientras que el segundo busca //a/b/c
en el repositorio externo.
Esto es especialmente relevante cuando se escriben reglas en el repositorio principal que hacen referencia a objetivos en el repositorio principal y se usarán desde repositorios externos.
Para obtener información sobre las diferentes formas en que puedes hacer referencia a los objetivos, consulta Patrones de objetivo.
Especificación léxica de una etiqueta
La sintaxis de etiquetas desalienta el uso de metacaracteres que tienen un significado especial para la shell. Esto ayuda a evitar problemas de comillas involuntarias y facilita la construcción de herramientas y secuencias de comandos que manipulan etiquetas, como el Lenguaje de consulta de Bazel.
A continuación, se incluyen los detalles precisos de los nombres de destinos permitidos.
Nombres de destino: package-name:target-name
target-name
es el nombre del destino dentro del paquete. El nombre de una regla es el valor del atributo name
en la declaración de la regla en un archivo BUILD
. El nombre de un archivo es su ruta de acceso en relación con el directorio que contiene el archivo BUILD
.
Los nombres de destino deben estar compuestos por completo de caracteres del conjunto a
a z
, A
a Z
, 0
a 9
y los símbolos de puntuación !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
.
Los nombres de archivo deben ser rutas de acceso relativas en formato normal, lo que significa que no deben comenzar ni terminar con una barra diagonal (por ejemplo, /foo
y foo/
están prohibidas) ni contener varias barras diagonales consecutivas como separadores de ruta (por ejemplo, foo//bar
). Del mismo modo, las referencias de nivel superior (..
) y las referencias de directorio actual (./
) están prohibidas.
Incorrecto: No uses ".." para hacer referencia a archivos en otros paquetes
Correcto: Usa "//package-name:filename".
Si bien es común usar /
en el nombre de un destino de archivo, evita usar /
en los nombres de las reglas. Especialmente cuando se usa la forma abreviada de
una etiqueta, puede confundir al lector. La etiqueta //foo/bar/wiz
siempre es un atajo para //foo/bar/wiz:wiz
, incluso si no hay un paquete foo/bar/wiz
de ese tipo. Nunca se refiere a //foo:bar/wiz
, incluso si ese destino existe.
Sin embargo, hay algunas situaciones en las que el uso de una barra es conveniente o, a veces, incluso necesario. Por ejemplo, el nombre de ciertas reglas debe coincidir con su archivo de origen principal, que puede estar en un subdirectorio del paquete.
Nombres de paquetes: //package-name:target-name
El nombre de un paquete es el nombre del directorio que contiene su archivo BUILD
,
en relación con el directorio de nivel superior del repositorio que lo contiene.
Por ejemplo: my/app
.
Los nombres de los paquetes deben estar compuestos por completo por caracteres del conjunto A
-Z
, a
-z
, 0
-9
, /
, -
, .
, @
y _
, y no pueden comenzar con una barra.
Para un lenguaje con una estructura de directorio que sea significativa para su sistema de módulos (por ejemplo, Java), es importante elegir nombres de directorios que sean identificadores válidos en el lenguaje.
Aunque Bazel admite destinos en el paquete raíz del lugar de trabajo (por ejemplo,
//:foo
), es mejor dejar ese paquete vacío para que todos los paquetes significativos
tengan nombres descriptivos.
Los nombres de los paquetes no pueden contener la subcadena //
ni terminar con una barra diagonal.
Reglas
Una regla especifica la relación entre las entradas y salidas, y los pasos para compilar las salidas. Las reglas pueden ser de muchos tipos diferentes (a veces llamados clase de regla), que producen bibliotecas y ejecutables compilados, ejecutables de prueba y otros resultados admitidos, como se describe en la Enciclopedia de compilación.
Los archivos BUILD
declaran destinos invocando reglas.
En el siguiente ejemplo, vemos la declaración del my_app
objetivo con la regla cc_binary
.
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
Cada invocación de regla tiene un atributo name
(que debe ser un nombre de destino válido) que declara un destino dentro del paquete del archivo BUILD
.
Cada regla tiene un conjunto de atributos; los atributos aplicables a una regla determinada, y la importancia y la semántica de cada atributo son una función del tipo de la regla. Consulta la Enciclopedia de compilaciones para obtener una lista de reglas y sus atributos correspondientes. Cada atributo tiene un nombre y un tipo. Algunos de los tipos comunes que puede tener un atributo son número entero, etiqueta, lista de etiquetas, cadena, lista de cadenas, etiqueta de salida y lista de etiquetas de salida. No es necesario especificar todos los atributos en cada regla. Así, los atributos forman un diccionario desde claves (nombres) hasta valores opcionales con tipo especificado.
El atributo srcs
presente en muchas reglas tiene el tipo "lista de etiquetas". Su valor, si está presente, es una lista de etiquetas, cada una de las cuales es el nombre de un objetivo que es una entrada para esta regla.
En algunos casos, el nombre del tipo de regla es un tanto arbitrario, y lo más interesante son los nombres de los archivos que genera la regla, y esto es cierto para genrules. Para obtener más información, consulta Reglas generales: genrule.
En otros casos, el nombre es significativo: para las reglas *_binary
y *_test
, por ejemplo, el nombre de la regla determina el nombre del ejecutable que produjo la compilación.
Este grafo acíclico dirigido sobre los destinos se denomina grafo de destino o grafo de dependencias de compilación, y es el dominio sobre el que opera la herramienta de consulta de Bazel.
Destinos | Archivos BUILD |