Funciones

Informar un problema Ver la fuente Nightly · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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 del paquete. Se usa como máximo una vez dentro de un paquete (archivo BUILD).

Se debe llamar a la función package() inmediatamente después de todas las instrucciones 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

Lista de etiquetas. El valor predeterminado es [].

Es la visibilidad predeterminada de las reglas en 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ública de forma predeterminada.

default_deprecation

Cadena. El valor predeterminado es "".

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

default_package_metadata

Lista de etiquetas. El valor predeterminado es [].

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

default_testonly

Booleano; el valor predeterminado es False, excepto cuando se indica lo contrario

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

En los paquetes de javatests, el valor predeterminado es True.

features

Cadenas de la lista. El valor predeterminado es [].

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

Esta función la usan principalmente las personas que trabajan en el sistema de compilación para etiquetar los paquetes que necesitan algún tipo de tratamiento especial. No uses este parámetro, a menos que alguien que trabaje en el sistema de compilación te lo solicite explícitamente.

Ejemplos

La siguiente declaración indica que las reglas de este paquete solo son visibles para los miembros del grupo de paquetes //foo:target. Las declaraciones de visibilidad individuales en una regla, si están presentes, anulan esta especificación.
package(default_visibility = ["//foo:target"])

package_group

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 controlar la visibilidad. Se puede hacer referencia a un destino visible públicamente desde cualquier paquete del árbol de origen. Solo se puede hacer referencia a un destino visible de forma privada dentro de su propio paquete (no en subpaquetes). Entre estos extremos, un destino puede permitir el acceso a su propio paquete y a cualquiera de los paquetes descritos por uno o más grupos de paquetes. Para obtener una explicación más detallada del sistema de visibilidad, consulta el atributo visibilidad.

Un paquete determinado se considera que está en el grupo si coincide con el atributo packages o si ya está incluido 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

Nombre (obligatorio)

Es un nombre único para este destino.

packages

Lista de cadenas; el valor predeterminado es []

Es una lista de cero o más especificaciones de paquetes.

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

  1. Nombre completo de un paquete, sin su repositorio, que comienza con una doble barra diagonal. Por ejemplo, //foo/bar especifica el paquete con ese nombre y que se encuentra en el mismo repositorio que el grupo de paquetes.
  2. Igual que antes, pero con un /... final. Por ejemplo, //foo/... especifica el conjunto de //foo y todos sus subpaquetes. //... especifica todos los paquetes del repositorio actual.
  3. Las cadenas public o private, que especifican, respectivamente, todos los paquetes o ningún paquete. (Este formulario requiere que se establezca la marca --incompatible_package_group_has_public_syntax).

Además, los dos primeros tipos de especificaciones de paquetes también pueden tener el prefijo - para indicar que están negados.

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 no son también subpaquetes de //foo/tests. (//foo se incluye, mientras que //foo/tests no se incluye).

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

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

Nota: Antes de Bazel 6.0, la especificación //... tenía un comportamiento heredado de ser igual a 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 serializaba como parte de bazel query --output=proto (o --output=xml), se omitían las barras iniciales. Por ejemplo, //pkg/foo/... se mostrará como \"pkg/foo/...\". Este comportamiento se corrige cuando se habilita --incompatible_package_group_includes_double_slash, que es el valor predeterminado después de Bazel 6.0.

includes

Lista de etiquetas. El valor predeterminado es [].

Otros grupos de paquetes que se incluyen en este.

Las etiquetas de este atributo deben hacer referencia a otros grupos de paquetes. Se considera que los paquetes de los grupos de paquetes a los que se hace referencia forman parte de este grupo de paquetes. Esta relación es transitiva: si el grupo de paquetes a incluye el grupo de paquetes b y b incluye el grupo de paquetes c, todos los paquetes de c también serán miembros de a.

Cuando se usa junto con 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 de 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"],
)

exports_files

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

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

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

Como comportamiento heredado, los archivos mencionados como entrada para una regla también se exportan con la visibilidad predeterminada hasta que se cambie la marca --incompatible_no_implicit_file_export. Sin embargo, no se debe confiar en este comportamiento y se debe migrar activamente.

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 la visibilidad, los archivos serán visibles para todos los paquetes, 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, para 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 ruta y devuelve una lista nueva, mutable y ordenada de sus rutas. Glob solo busca archivos en su propio paquete y solo busca archivos fuente (no archivos generados ni otros destinos).

La etiqueta de un archivo fuente se incluye en el resultado si la ruta de acceso relativa al paquete del archivo coincide con cualquiera de los patrones include y con ninguno de los patrones exclude.

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

Ejemplos:
  • foo/bar.txt coincide exactamente con el archivo foo/bar.txt de este paquete.
  • foo/*.txt coincide con todos los archivos del directorio foo/ si el archivo termina con .txt (a menos que foo/ sea un subpaquete).
  • foo/a*.htm* coincide con todos los archivos del directorio foo/ que comienzan con a, luego tienen una cadena arbitraria (que podría estar vacía), luego tienen .htm y terminan con otra cadena 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 en 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 un segmento por sí solo.

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

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

Existen varias limitaciones y advertencias importantes:

  1. Dado que glob() se ejecuta durante la evaluación del archivo BUILD, glob() solo coincide con los archivos de tu árbol de origen, nunca con los archivos generados. Si compilas un destino que requiere archivos fuente y archivos generados, debes agregar una lista explícita de archivos generados al comodín. Consulta el ejemplo a continuación con :mylib y :gen_java_srcs.

  2. Si una regla tiene el mismo nombre que un archivo fuente coincidente, la regla "eclipsará" el archivo.

    Para comprender esto, recuerda que glob() devuelve 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 de acceso coincidentes de forma explícita. Por ejemplo, si glob() genera ["Foo.java", "bar/Baz.java"], pero también hay una regla en el paquete llamada "Foo.java" (lo que se permite, aunque Bazel advierte sobre ello), el consumidor de glob() usará la regla "Foo.java" (sus resultados) en lugar del archivo "Foo.java". Consulta el problema #10395 de GitHub para obtener más detalles.

  3. Los globs pueden coincidir con archivos en subdirectorios. Además, los nombres de los subdirectorios pueden incluir comodines. Sin embargo…
  4. Las etiquetas no pueden cruzar el límite del paquete, y glob no coincide con los archivos de los subpaquetes.

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

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

En general, debes intentar proporcionar una extensión adecuada (p.ej., *.html) en lugar de usar un asterisco simple para un patrón de comodín. El nombre más explícito se documenta por sí mismo y garantiza que no coincida accidentalmente con archivos de copia de seguridad o archivos de guardado automático de Emacs/vi/…

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 Ejemplo de expansión de glob a continuación.

Ejemplos de glob

Crea una biblioteca de Java compilada a partir de todos los archivos Java de este directorio y 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",
    ],
    ...
)

Incluye todos los archivos .txt en el directorio testdata, excepto experimental.txt. Ten en cuenta que no se incluirán los archivos de los subdirectorios de testdata. Si quieres incluir esos archivos, usa un comodín recursivo (**).

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

Ejemplos de glob recursivo

Haz que la prueba dependa de todos los archivos txt del directorio testdata y de cualquiera de sus subdirectorios (y sus subdirectorios, y así sucesivamente). Se ignoran los subdirectorios que contienen un archivo BUILD. (Consulta las limitaciones y advertencias anteriores).

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 todos los subdirectorios, excepto aquellos cuya ruta incluya un directorio llamado testing. Se debe evitar este patrón siempre que sea posible, 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 expansión de globs

Crea una genrule individual para *_test.cc en el directorio actual que cuente 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 BUILD anterior se encuentra en el paquete //foo y el paquete contiene tres archivos coincidentes, a_test.cc, b_test.cc y c_test.cc, ejecutar bazel query '//foo:all' mostrará 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

seleccionar

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

select() es la función auxiliar que hace que un atributo de regla sea configurable. Puede reemplazar el lado derecho de casi cualquier asignación de atributos para que su valor dependa de las marcas de Bazel de la línea de comandos. Por ejemplo, puedes usarlo para definir dependencias específicas de la plataforma o para incorporar diferentes recursos según si una regla se compila en modo "desarrollador" o "versión".

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 normal de lista de etiquetas por una llamada a select que asigne condiciones de configuración a 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 esperado de valores. Luego, el valor de mytarget#srcs se convierte en la lista de etiquetas que coincida con la invocación actual.

Notas:

  • Se selecciona exactamente una condición en cualquier invocación.
  • Si coinciden varias condiciones y una es una especialización de las demás, prevalece la especialización. La condición B se considera una especialización de la condición A si B tiene todas las mismas marcas y valores de restricción que A, además de algunas marcas o valores de restricción adicionales. Esto también significa que la resolución de especialización no está diseñada para crear un orden, como se demuestra en el Ejemplo 2 a continuación.
  • Si coinciden varias condiciones y una no es una especialización de todas las demás, Bazel falla con un error, a menos que todas las condiciones se resuelvan en el mismo valor.
  • Se considera que la seudoe etiqueta especial //conditions:default coincide si no coincide ninguna otra condición. Si se omite esta condición, debe coincidir alguna otra regla para evitar un error.
  • select se puede incorporar dentro de una asignación de atributos 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 con nonconfigurable en su documentación.

    subpaquetes

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

    subpackages() es una función auxiliar, similar a glob(), que enumera los subpaquetes en lugar de los archivos y directorios. Utiliza los mismos patrones de ruta de acceso que glob() y puede coincidir con cualquier subpaquete que sea un descendiente directo del archivo BUILD que se está cargando actualmente. 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á ordenada y contiene rutas de acceso relativas al paquete de carga actual que coinciden con los patrones proporcionados 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 a esta función directamente, los usuarios utilicen el módulo "subpackages" de skylib.