Funciones

Informa de un problema Ver fuente

Contenido

paquete

package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)

Esta función declara los metadatos que se aplican a cada regla posterior del paquete. Se utiliza como máximo una vez dentro de un paquete (archivo BUILD).

La función package() se debe llamar justo después de todas las sentencias load() en la parte superior del archivo, antes de cualquier regla.

Argumentos

Atributo Descripción
default_applicable_licenses

Alias de default_package_metadata.

default_visibility

List of labels; optional

La visibilidad predeterminada de las reglas de este paquete.

Cada regla de este paquete tiene la visibilidad especificada en este atributo, a menos que se especifique lo contrario en el atributo visibility de la regla. Para obtener información detallada sobre la sintaxis de este atributo, consulta la documentación de visibilidad. La visibilidad predeterminada del paquete no se aplica a exports_files, que es público de forma predeterminada.

default_deprecation

String; optional

Configura el mensaje deprecation predeterminado para todas las reglas de este paquete.

default_package_metadata

List of labels; optional

Establece una lista predeterminada de objetivos de metadatos que se aplican a todos los demás destinos del paquete. Por lo general, son objetivos relacionados con el paquete y las declaraciones de licencia de OSS. Consulta rules_license para ver ejemplos.

default_testonly

Boolean; optional; default is False except as noted

Configura la propiedad testonly predeterminada para todas las reglas de este paquete.

En paquetes en javatests, el valor predeterminado es 1.

features

List strings; optional

Establece varias marcas que afectan la semántica de este archivo BUILD.

Esta función se utiliza principalmente para las personas que trabajan en el sistema de compilación a fin de etiquetar paquetes que necesitan algún tipo de manejo especial. No lo uses a menos que lo solicite explícitamente una persona que trabaja en el sistema de compilación.

Ejemplos

La declaración que aparece a continuación declara que las reglas de este paquete solo son visibles para los miembros del grupo de paquetes //foo:target. Las declaraciones de visibilidad individual de una regla, si las hay, anulan esta especificación.
package(default_visibility = ["//foo:target"])

paquete_paquete

package_group(name, packages, includes)

Esta función define un conjunto de paquetes y asocia una etiqueta con el conjunto. Se puede hacer referencia a la etiqueta en los atributos visibility.

Los grupos de paquetes se usan principalmente para el control de visibilidad. Se puede hacer referencia a un objetivo visible de forma pública desde cada paquete en el árbol de fuentes. Solo se puede hacer referencia a un destino visible de forma privada dentro de su propio paquete (no subpaquetes). Entre estos extremos, un destino puede permitir el acceso a su propio paquete, además de cualquiera de los paquetes que describe uno o más grupos de paquetes. Para obtener una explicación más detallada del sistema de visibilidad, consulta el atributo visibilidad.

Se considera que un paquete determinado está en el grupo si coincide con el atributo packages o si ya está contenido en uno de los otros grupos de paquetes mencionados en el atributo includes.

Técnicamente, los grupos de paquetes son destinos, pero no se crean con reglas y no tienen protección de visibilidad.

Argumentos

Atributo Descripción
name

Name; required

Es un nombre único para este destino.

packages

List of strings; optional

Una lista de cero o más especificaciones del paquete

Cada string de especificación de paquete puede tener una de las siguientes formas:

  1. El nombre completo de un paquete, sin su repositorio, que comienza con una barra doble. Por ejemplo, //foo/bar especifica el paquete que tiene ese nombre y que se encuentra en el mismo repositorio que el grupo de paquetes.
  2. Como se muestra arriba, pero con un /... al final. Por ejemplo, //foo/... especifica el conjunto de //foo y todos sus subpaquetes. //... especifica todos los paquetes del repositorio actual.
  3. Las strings public o private, que especifican todos los paquetes o ninguno. (Para este formulario, se debe configurar la marca --incompatible_package_group_has_public_syntax).

Además, los dos primeros tipos de especificaciones del paquete también pueden tener el prefijo - para indicar que se negaron.

El grupo de paquetes contiene cualquier paquete que coincida con, al menos, una de sus especificaciones positivas y ninguna de sus especificaciones negativas. Por ejemplo, el valor [//foo/..., -//foo/tests/...] incluye todos los subpaquetes de //foo que tampoco son subpaquetes de //foo/tests. (//foo en sí está incluido, mientras que //foo/tests no lo está).

Además de la visibilidad pública, no hay forma de especificar paquetes de forma directa fuera del repositorio actual.

Si falta este atributo, equivale a establecerlo en una lista vacía, que también es lo mismo que establecerlo en una lista que solo contenga private.

Nota: Antes de Bazel 6.0, la especificación //... tenía un comportamiento heredado de igual que public. Este comportamiento se corrige cuando se habilita --incompatible_fix_package_group_reporoot_syntax, que es el valor predeterminado después de Bazel 6.0.

Nota: Antes de Bazel 6.0, cuando este atributo se serializa como parte de bazel query --output=proto (o --output=xml), se omiten las barras diagonales. Por ejemplo, //pkg/foo/... se mostrará como \"pkg/foo/...\". Este comportamiento se corrige cuando se habilita --incompatible_package_group_includes_double_slash, que es la configuración predeterminada después de Bazel 6.0.

includes

List of labels; optional

Otros grupos de paquetes incluidos en este

Las etiquetas de este atributo deben hacer referencia a otros grupos de paquetes. Los paquetes en los grupos de paquetes a los que se hace referencia se toman para formar parte de este grupo de paquetes. Esto es transitivo: Si el grupo de paquetes a incluye el grupo de paquetes b, y b incluye el grupo de paquetes c, cada paquete en c también será miembro de a.

Cuando se usa junto con las especificaciones de paquetes negadas, ten en cuenta que el conjunto de paquetes para cada grupo se calcula primero de forma independiente y, luego, los resultados se unen. Esto significa que las especificaciones negadas en un grupo no tienen efecto en las especificaciones de otro grupo.

Ejemplos

La siguiente declaración package_group especifica un grupo de paquetes llamado “tropical” que contiene frutas tropicales.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

Las siguientes declaraciones especifican los grupos de paquetes de una aplicación ficticia:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

archivos_exportaciones

exports_files([label, ...], visibility, licenses)

exports_files() especifica una lista de archivos que pertenecen a este paquete que se exportaron a otros paquetes.

El archivo BUILD de un paquete solo puede referirse directamente a los archivos de origen que pertenecen a otro paquete si se exportan de forma explícita con una declaración exports_files(). Obtén más información sobre la visibilidad de los archivos.

Como comportamiento heredado, los archivos también mencionados como entrada a una regla se exportan con la visibilidad predeterminada hasta que se gire la marca --incompatible_no_implicit_file_export. Sin embargo, este comportamiento no debería depender de él ni migrarse de forma activa.

Argumentos

El argumento es una lista de nombres de archivos dentro del paquete actual. También se puede especificar una declaración de visibilidad; en este caso, los archivos serán visibles para los destinos especificados. Si no se especifica ninguna visibilidad, los archivos serán visibles para cada paquete, incluso si se especificó una visibilidad predeterminada del paquete en la función package. También se pueden especificar las licencias.

Ejemplo

En el siguiente ejemplo, se exporta golden.txt, un archivo de texto del paquete test_data, de modo que otros paquetes puedan usarlo, por ejemplo, en el atributo data de las pruebas.

# from //test_data/BUILD

exports_files(["golden.txt"])

glob

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob es una función auxiliar que encuentra todos los archivos que coinciden con ciertos patrones de rutas de acceso y muestra una lista nueva, mutable y ordenada de sus rutas. Glob solo busca archivos en su propio paquete y busca solo archivos fuente (no archivos generados ni otros destinos).

Se incluye la etiqueta de un archivo de origen en el resultado si la ruta relativa del paquete del archivo coincide con alguno de los patrones include y ninguno de los patrones exclude.

Las listas include y exclude contienen patrones de ruta de acceso relacionados con el paquete actual. Cada patrón puede constar de uno o más segmentos de ruta. Como siempre, con las rutas de acceso de Unix, estos segmentos están separados por /. Los segmentos pueden contener el comodín *: coincide con cualquier substring del segmento de la ruta de acceso (incluso la substring vacía), sin incluir el separador de directorios /. Este comodín se puede usar varias veces dentro de un segmento de ruta de acceso. Además, el comodín ** puede coincidir con cero o más segmentos de ruta completos, pero debe declararse como un segmento de ruta independiente.

Ejemplos:
  • foo/bar.txt coincide exactamente con el archivo foo/bar.txt de este paquete
  • foo/*.txt coincide con todos los archivos en el directorio foo/ si el archivo termina con .txt (a menos que foo/ sea un subpaquete).
  • foo/a*.htm* coincide con cada archivo en el directorio foo/ que comienza con a, luego tiene una string arbitraria (puede estar vacía), después tiene .htm y termina con otra string arbitraria; como foo/axx.htm y foo/a.html o foo/axxx.html
  • **/a.txt coincide con cada archivo a.txt en cada subdirectorio de este paquete
  • **/bar/**/*.txt coincide con cada archivo .txt en cada subdirectorio de este paquete, si al menos un directorio de la ruta resultante se llama bar, como xxx/bar/yyy/zzz/a.txt o bar/a.txt (recuerda que ** también coincide con cero segmentos) o bar/zzz/a.txt
  • ** coincide con cada archivo en cada subdirectorio de este paquete
  • foo**/a.txt es un patrón no válido, ya que ** debe ser independiente como segmento

Si el argumento exclude_directories está habilitado (configurado en 1), se omitirán los archivos del directorio de tipo de los resultados (el valor predeterminado es 1).

Si el argumento allow_empty se establece en False, la función glob generará un error si, de lo contrario, el resultado sería la lista vacía.

Existen varias limitaciones y advertencias importantes:

  1. Dado que glob() se ejecuta durante la evaluación de archivos de COMPILACIÓN, glob() coincide con los archivos del árbol de fuentes, que nunca se generaron. Si compilas un destino que requiere archivos de origen y generados, debes agregar una lista explícita de archivos generados al glob. Consulta el siguiente ejemplo con :mylib y :gen_java_srcs.

  2. Si una regla tiene el mismo nombre que un archivo de origen coincidente, la regla “sombreará” el archivo.

    Para entender esto, recuerda que glob() muestra una lista de rutas de acceso, por lo que usar glob() en el atributo de otras reglas (p.ej., srcs = glob(["*.cc"])) tiene el mismo efecto que enumerar las rutas coincidentes de forma explícita. Si, por ejemplo, glob() produce ["Foo.java", "bar/Baz.java"], pero también hay una regla en el paquete llamada “Foo.java” (que está permitida, aunque Bazel lo advierta), entonces el consumidor de glob() usará la regla “Foo.java” (sus resultados) en lugar del archivo “Foo.java”. Consulta el problema número 10395 de GitHub para obtener más detalles.

  3. Es posible que los vistazos coincidan con los archivos de los subdirectorios. Además, los nombres de los subdirectorios pueden tener comodines. Sin embargo...
  4. No se permite que las etiquetas crucen el límite del paquete y el glob no coincide con los archivos de los subpaquetes.

    Por ejemplo, la expresión glob **/*.cc en el paquete x no incluye x/y/z.cc si x/y existe como paquete (ya sea x/y/BUILD o en cualquier otra parte de la ruta del paquete). Esto significa que el resultado de la expresión glob depende de la existencia de los archivos BUILD, es decir, la misma expresión glob incluiría x/y/z.cc si no hubiera un paquete llamado x/y o se marcó como borrado con la marca --DELETED_packages.

  5. La restricción anterior se aplica a todas las expresiones glob, independientemente de los comodines que usen.
  6. Un archivo oculto con un nombre que comienza con . coincide por completo con los comodines ** y *. Si deseas hacer coincidir un archivo oculto con un patrón compuesto, este debe comenzar con un .. Por ejemplo, * y .*.txt coincidirán con .foo.txt, pero *.txt no lo hará. Los directorios ocultos también coinciden de la misma manera. Los directorios ocultos pueden incluir archivos que no son necesarios como entradas y pueden aumentar la cantidad de archivos no necesarios y el consumo de memoria. Para excluir directorios ocultos, agrégalos al argumento de la lista "excluir".
  7. El comodín "**" tiene un caso límite: el patrón "**" no coincide con la ruta del directorio del paquete. Es decir, glob(["**"], exclude_directories = 0) coincide con todos los archivos y directorios de forma transitiva y se encuentra en el directorio del paquete actual (pero, por supuesto, no vamos a los directorios de subpaquetes; consulta la nota anterior sobre eso).

En general, debes intentar proporcionar una extensión adecuada (p.ej., *.html) en lugar de usar un '*' simple para un patrón glob. El nombre más explícito es la documentación propia y garantiza que no hagas coincidir accidentalmente los archivos de copia de seguridad ni los archivos emacs/vi/... que se guardan automáticamente.

Cuando escribes reglas de compilación, puedes enumerar los elementos del glob. Esto permite generar reglas individuales para cada entrada, por ejemplo. Consulta la sección de ejemplo glob expandido a continuación.

Ejemplos de Glob

Crea una biblioteca de Java compilada a partir de todos los archivos Java de este directorio y de todos los archivos generados por la regla :gen_java_srcs.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

Incluir todos los archivos txt en los datos de prueba del directorio, excepto experimental.txt Ten en cuenta que no se incluirán los archivos de los subdirectorios de testdata. Si deseas que se incluyan esos archivos, usa un glob recursivo (**).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

Ejemplos de globos recursivos

Haz que la prueba dependa de todos los archivos txt del directorio testdata y de cualquiera de sus subdirectorios (y sus subdirectorios, entre otros). Se ignoran los subdirectorios que contienen un archivo BUILD. (Consulta las limitaciones y advertencias más arriba).

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

Crea una biblioteca compilada a partir de todos los archivos Java de este directorio y de todos los subdirectorios, excepto aquellos cuya ruta de acceso incluya un directorio llamado prueba. Si es posible, debes evitar este patrón, ya que puede reducir la incrementalidad de la compilación y, por lo tanto, aumentar los tiempos de compilación.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

Ejemplos de globo terráqueo expandido

Crea una genrule individual para *_test.cc en el directorio actual que calcule la cantidad de líneas del archivo.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

Si el archivo de COMPILACIÓN anterior está en el paquete //foo y el paquete contiene tres archivos coincidentes, a_test.cc, b_test.cc y c_test.cc, entonces la ejecución de bazel query '//foo:all' mostrará una lista de todas las reglas que se generaron:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

select

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() es la función auxiliar que permite que un atributo de la regla sea configurable. Puede reemplazar el lado derecho de casi cualquier asignación de atributo, por lo que su valor depende de las marcas de Bazel de la línea de comandos. Puedes usarlo, por ejemplo, para definir dependencias específicas de la plataforma o incorporar diferentes recursos según si una regla se compila en modo “desarrollador” o en modo de “lanzamiento”.

El uso básico es el siguiente:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

Esto hace que el atributo srcs de un sh_binary se pueda configurar reemplazando su asignación de lista de etiquetas normal por una llamada select que asigna las condiciones de configuración a los valores coincidentes. Cada condición es una referencia de etiqueta a un config_setting o constraint_value, que “coincide” si la configuración del objetivo coincide con un conjunto de valores esperado. El valor de mytarget#srcs se convierte en cualquier lista de etiquetas que coincida con la invocación actual.

Notas:

  • En cada invocación se selecciona solo una condición.
  • Si varias condiciones coinciden y una es una especialización de las otras, entonces tendrá prioridad. La condición B se considera una especialización de la condición A si B tiene las mismas marcas y los mismos valores de restricción que A, más algunas marcas o valores de restricción adicionales. Esto también significa que la resolución de la especialización no está diseñada para crear un orden, como se muestra en el ejemplo 2 a continuación.
  • Si varias condiciones coinciden y una no es una especialización de las todas, Bazel falla con un error, a menos que todas las condiciones se resuelvan en el mismo valor.
  • Se considera que la pseudoetiqueta especial //conditions:default coincide si no coincide ninguna otra condición. Si se omite esta condición, alguna otra regla debe coincidir para evitar un error.
  • select se puede incorporar dentro de una asignación de atributo más grande. Por lo tanto, srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) y srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) son expresiones válidas.
  • select funciona con la mayoría de los atributos, pero no con todos. Los atributos incompatibles se marcan como nonconfigurable en su documentación.

    subpaquetes

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() es una función auxiliar, similar a glob() que enumera subpaquetes en lugar de archivos y directorios. Usa los mismos patrones de ruta de acceso que glob() y puede coincidir con cualquier subpaquete que sea subordinado directo del archivo de COMPILACIÓN que se está cargando. Consulta glob para obtener una explicación detallada y ejemplos de patrones de inclusión y exclusión.

    La lista resultante de subpaquetes que se muestra está en orden y contiene rutas de acceso relacionadas con el paquete de carga actual que coinciden con los patrones especificados en include y no con los de exclude.

    Ejemplo

    En el siguiente ejemplo, se enumeran todos los subpaquetes directos del paquete foo/BUILD.

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

    En general, se prefiere que, en lugar de llamar directamente a esta función, los usuarios usen el módulo "subpackages" de skylib.