Etiquetas

Informa un problema Ver código fuente

Todos los objetivos pertenecen a exactamente un paquete. El nombre de un objetivo se denomina etiqueta. Cada etiqueta identifica un destino de manera única. Una etiqueta típica con formato canónico tiene el siguiente aspecto:

@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 //. Por lo tanto, dentro de @myrepo, esta etiqueta suele escribirse como

//my/app/main:app_binary

La segunda parte de la etiqueta es el nombre del paquete no calificado my/app/main, la ruta de acceso al paquete relacionado 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 forma opcional, los 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 regla general, los dos puntos se omiten para los archivos, pero se conservan para las reglas, pero no tienen importancia.

La parte de la etiqueta después de los dos puntos, app_binary es el nombre de destino no calificado. Cuando coincide con el último componente de la ruta del paquete, se pueden omitir este y los dos puntos. Por lo tanto, estas dos etiquetas son equivalentes:

//my/app/lib
//my/app/lib:lib

El nombre de un destino de archivo en un subdirectorio del paquete es la ruta de acceso 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 strings como //my/app y @some_repo//my/app tienen dos significados, según el contexto en el que se usen: cuando Bazel espera una etiqueta, significa //my/app:app y @some_repo//my/app:app, respectivamente. Sin embargo, cuando Bazel espera un paquete (p.ej., en las especificaciones package_group), hacen 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; esto no sucede. Recuerda que es equivalente a //my/app:app, por lo que nombra el destino app en el paquete my/app del repositorio actual.

Sin embargo, se recomienda usar //my/app para hacer referencia a un paquete en la especificación de un archivo 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; el identificador del repositorio y el nombre del paquete siempre se deben especificar en este caso. Por ejemplo, si el árbol fuente 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 contiene un archivo llamado testdepot.zip. Hay dos maneras (una incorrecta, 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 este 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 muy relevante cuando se escriben reglas en el repositorio principal que hacen referencia a destinos en el repositorio principal y se usarán desde repositorios externos.

Para obtener información sobre las diferentes formas de hacer referencia a los destinos, consulta Patrones de destino.

Especificación léxica de una etiqueta

La sintaxis de etiquetas no recomienda el uso de metacaracteres que tengan un significado especial para la shell. Esto ayuda a evitar los problemas relacionados con citas inadvertidas y facilita la creación de herramientas y secuencias de comandos que manipulan las etiquetas, como el lenguaje de consulta de Bazel.

A continuación, se indican los detalles precisos de los nombres de destino permitidos.

Nombres de las orientaciones: 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 nombre de ruta en relación con el directorio que contiene el archivo BUILD.

Los nombres de destino deben estar compuestos completamente por caracteres del conjunto a-z, AZ, 09 y los símbolos de puntuación !%-@^_"#$&'()*-+,;<=>?[]{|}~/..

Los nombres de archivo deben ser nombres de ruta relativos en el formato normal, lo que significa que no deben comenzar ni terminar con una barra (por ejemplo, /foo y foo/ están prohibidos) ni contener varias barras consecutivas como separadores de ruta (por ejemplo, foo//bar). Del mismo modo, se prohíben las referencias de nivel superior (..) y las referencias del directorio actual (./).

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. Esto puede confundir al lector, en especial cuando se usa una forma abreviada de una etiqueta. La etiqueta //foo/bar/wiz siempre es una abreviatura de //foo/bar/wiz:wiz, incluso si no existe ese paquete foo/bar/wiz. Nunca hace referencia 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, necesario. Por ejemplo, el nombre de ciertas reglas debe coincidir con su archivo de origen principal, que puede residir en un subdirectorio del paquete.

Nombres de los 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 completamente por caracteres del conjunto A-Z, az, 09, '/', '-', '.', '@' y '_', y no pueden comenzar con una barra.

En el caso de un lenguaje con una estructura de directorio que es importante para su sistema de módulo (por ejemplo, Java), es importante elegir nombres de directorio 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 substring // ni terminar con una barra.

Reglas

Una regla especifica la relación entre las entradas y salidas, y los pasos para compilar las salidas. Las reglas pueden ser de uno de muchos tipos diferentes (a veces llamados clases de reglas), que producen ejecutables y bibliotecas compilados, ejecutables de prueba y otros resultados admitidos, como se describe en la Enciclopedia de compilaciones.

Los archivos BUILD declaran objetivos mediante la invocación de reglas.

En el siguiente ejemplo, vemos la declaración del my_app de destino 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 declare un objetivo dentro del paquete del archivo BUILD.

Cada regla tiene un conjunto de atributos. Los atributos aplicables para una regla determinada, y la importancia y semántica de cada atributo son una función del tipo de 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úmeros enteros, etiquetas, lista de etiquetas, strings, listas de strings, etiquetas de resultados y listas de etiquetas de resultados. No es necesario especificar todos los atributos en cada regla. Por lo tanto, los atributos forman un diccionario desde las claves (nombres) hasta los valores opcionales de tipo escrito.

El atributo srcs presente en muchas reglas tiene el tipo “lista de etiquetas”. Su valor, si está presente, es una lista de etiquetas, y cada uno es el nombre de un destino que es una entrada de esta regla.

En algunos casos, el nombre de la categoría de regla es un tanto arbitrario, y más interesantes son los nombres de los archivos que genera la regla, y esto es verdadero de las genrules. Para obtener más información, consulta Reglas generales: genrule.

En otros casos, el nombre es significativo: para reglas *_binary y *_test, por ejemplo, el nombre de la regla determina el nombre del ejecutable producido por la compilación.

Este grafo acíclico dirigido sobre objetivos se denomina gráfico de destino o gráfico de dependencias de compilación y es el dominio sobre el que opera la herramienta de consulta de Bazel.

Objetivos Archivos BUILD