Crear variables

Informar un problema Ver fuente Por la noche · 7.4 de Google Cloud. 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Las variables "Make" son una clase especial de variables de cadena expandibles disponibles para los atributos marcados como "Sujeto a la sustitución de "variable Make".

Se pueden usar, por ejemplo, para insertar rutas de cadenas de herramientas específicas en acciones de compilación creadas por el usuario.

Bazel proporciona variables predefinidas, que están disponibles para todos los destinos, y variables personalizadas, que se definen en destinos de dependencia y solo están disponibles para los destinos que dependen de ellas.

El motivo del término "Make" es histórico: la sintaxis y la semántica de estas variables se diseñaron originalmente para coincidir con GNU Make.

Usar

Los atributos marcados como “Sujeto a la sustitución de la "variable de Make"” pueden hacer referencia a la variable FOO de "Make" de la siguiente manera:

my_attr = "prefix $(FOO) suffix"

En otras palabras, cualquier subcadena que coincida con $(FOO) se expande. al valor de FOO. Si ese valor es "bar", el valor final string se convierte en:

my_attr = "prefix bar suffix"

Si FOO no corresponde a una variable conocida por el consumidor destino, Bazel falla con un error.

"Marca" variables cuyos nombres son símbolos que no son letras, como @, también se puede hacer referencia con solo un signo de dólar, sin los paréntesis. Por ejemplo:

my_attr = "prefix $@ suffix"

Escribir $ como un literal de string (es decir, para evitar la variable expansión), escribe $$.

Variables predefinidas

Cualquier atributo marcado como "Sujeto a la sustitución de "variable de Make" en cualquier destino puede hacer referencia a las variables predefinidas de "Make".

Para ver la lista de estas variables y sus valores para un conjunto determinado de opciones de compilación, ejecuta

bazel info --show_make_env [build options]

y observa las líneas de salida superiores con letras mayúsculas.

Consulta un ejemplo de variables predefinidas.

Variables de opciones de la cadena de herramientas

Variables de ruta de acceso

  • BINDIR: Es la base del árbol binario generado para la arquitectura de destino.

    Ten en cuenta que se puede usar un árbol diferente para los programas que se ejecutan durante la compilación en la arquitectura del host para admitir la compilación cruzada.

    Si quieres ejecutar una herramienta desde un genrule, la forma recomendada de obtener su ruta de acceso es $(execpath toolname), en la que nombredeherramienta debe aparecer en el atributo tools de genrule.

  • GENDIR La base del árbol de código generado para la arquitectura de destino.

Variables de arquitectura de máquina

  • TARGET_CPU La CPU de la arquitectura de destino, p.ej., k8

Variables predefinidas de genrule

Las siguientes opciones están disponibles especialmente para los clientes de genrule el atributo cmd y son por lo general, es importante para que ese atributo funcione.

Consulta un ejemplo de variables de genrule predefinidas.

  • OUTS: Es la lista outs de genrule. Si solo tienes un archivo de salida, también puedes usar $@.
  • SRCS: Es la lista srcs de genrule (o más). precisamente: los nombres de las rutas de acceso de los archivos correspondientes a las etiquetas del srcs). Si solo tienes un archivo de origen, también puedes usar $<.
  • <: SRCS, si es un archivo único De lo contrario, activadores un error de compilación.
  • @: OUTS, si es un solo archivo. De lo contrario, se activa un error de compilación.
  • RULEDIR: El directorio de salida del destino, es decir, el directorio correspondiente al nombre del paquete que contiene el archivo en el árbol genfiles o bin. Para //my/pkg:my_genrule, esto siempre termina en my/pkg, incluso si las salidas de //my/pkg:my_genrule están en subdirectorios.

  • @D: El directorio de salida. Si outs tiene una entrada, se expande al directorio que contiene ese archivo. Si tiene varios de entrada, se expande al directorio raíz del paquete en el genfiles, incluso si todos los archivos de salida están en la misma subdirectorio.

    Nota: Usa RULEDIR en lugar de @D porque RULEDIR tiene una semántica más simple y se comporta de la misma manera independientemente de la cantidad de archivos de salida.

    Si la genrule necesita generar archivos intermedios temporales (quizás como resultado del uso de alguna otra herramienta, como un compilador), debería intentar escribirlos en @D (aunque /tmp también admite escritura) y quítalas antes de finalizar.

    En especial, evita escribir en directorios que contengan entradas. Pueden estar en sistemas de archivos de solo lectura. Incluso si no fuera así, hacerlo eliminaría el árbol de origen.

Variables predefinidas de ruta de fuente/salida

Las variables predefinidas execpath, execpaths, rootpath, rootpaths, location y locations toman parámetros de etiqueta (p. ej., $(execpath //foo:bar)) y sustituyen las rutas de acceso a los archivos que indica esa etiqueta.

Para los archivos de origen, es la ruta de acceso relativa a la raíz de tu lugar de trabajo. En el caso de los archivos que son resultados de reglas, esta es la ruta de acceso de salida del archivo (consulta la explicación de los archivos de salida a continuación).

Consulta un ejemplo de variables de ruta predefinidas.

  • execpath: Indica la ruta debajo de la execroot en la que Bazel ejecuta acciones de compilación.

    En el ejemplo anterior, Bazel ejecuta todas las acciones de compilación en el directorio vinculado. a través del symlink bazel-myproject en la raíz de tu espacio de trabajo. El el archivo de origen empty.source está vinculado en la ruta de acceso bazel-myproject/testapp/empty.source Por lo tanto, su ruta de ejecución (que es la subruta debajo de la raíz) es testapp/empty.source. Esta es la ruta de acceso que las acciones de compilación pueden usar para encontrar el archivo.

    Los archivos de salida se almacenan en etapa intermedia de manera similar, pero también tienen el prefijo de la ruta secundaria. bazel-out/cpu-compilation_mode/bin (o para las salidas de herramientas: bazel-out/cpu-opt-exec-hash/bin). En el ejemplo anterior, //testapp:app es una herramienta porque aparece en Atributo tools de show_app_output. Por lo tanto, su archivo de salida app se escribe en bazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app. Por lo tanto, la ruta de ejecución es bazel-out/cpu-opt-exec-hash/bin/testapp/app. Este prefijo adicional permite crear el mismo objetivo para, digamos, dos CPU diferentes en la misma compilación sin que los resultados se obstruyan entre sí.

    La etiqueta que se pasa a esta variable debe representar exactamente un archivo. Para las etiquetas que representan archivos de origen, esto es verdadero automáticamente. Para etiquetas que representan reglas, esta debe generar exactamente un resultado. Si este es el caso false o la etiqueta presenta errores de formato, la compilación fallará con un error.

  • rootpath: Denota la ruta de acceso que un objeto binario compilado puede usar para lo siguiente: Encuentra una dependencia en el tiempo de ejecución en relación con el subdirectorio de sus runfiles. que corresponde al repositorio principal. Nota: Esta opción solo funciona si --enable_runfiles está habilitado, lo cual no sucede en Windows de forma predeterminada. Usa rlocationpath en su lugar para la compatibilidad multiplataforma.

    Es similar a execpath, pero elimina la configuración. prefijos descritos anteriormente. En el ejemplo anterior, esto significa que tanto empty.source y app usan valores relativos puros del espacio de trabajo rutas de acceso: testapp/empty.source y testapp/app.

    El rootpath de un archivo en un repositorio externo repo comenzará con ../repo/, seguido de la ruta de acceso relativa al repositorio.

    Tiene los mismos requisitos de "un solo resultado" que execpath.

  • rlocationpath: Es la ruta de acceso que un objeto binario compilado puede pasar a la función Rlocation de una biblioteca de runfiles para encontrar una dependencia en el tiempo de ejecución, ya sea en el directorio de runfiles (si está disponible) o con el manifiesto de runfiles.

    Esto es similar a rootpath en que no contiene prefijos de configuración, pero difiere en que siempre comienza con el nombre del repositorio. En el ejemplo anterior, esto significa que empty.source y app generan las siguientes rutas de acceso: myproject/testapp/empty.source y myproject/testapp/app.

    El rlocationpath de un archivo en un repositorio externo repo comenzará con repo/, seguido de relativa al repositorio.

    Pasar esta ruta de acceso a un objeto binario y resolverlo en una ruta del sistema de archivos mediante Las bibliotecas de archivos de ejecución es el enfoque preferido para encontrar dependencias en tiempo de ejecución. En comparación con rootpath, tiene la ventaja de que funciona en todas las plataformas y, incluso, si el directorio de runfiles no está disponible.

    Esto tiene la misma configuración de "solo una salida" como execpath.

  • location: Es un sinónimo de execpath o rootpath, según el atributo que se expanda. Este es sobre el comportamiento heredado previo a Starlark y no se recomienda, a menos que sepas bien para una regla en particular. Ver #2475 para conocer los detalles.

execpaths, rootpaths, rlocationpaths y locations son las variaciones en plural de execpath, rootpath, rlocationpaths y location, respectivamente. Admiten etiquetas que producen varios resultados, en cuyo caso cada resultado se enumera por separado por un espacio. Reglas sin salida y con formato incorrecto las etiquetas producen errores de compilación.

Todas las etiquetas a las que se hace referencia deben aparecer en el srcs del destino de consumo. archivos de salida, o deps. De lo contrario, la compilación falla. Los destinos de C++ pueden También hacen referencia a etiquetas en data.

Las etiquetas no tienen que estar en formato canónico: foo, :foo y //somepkg:foo son adecuadas.

Variables personalizadas

"Marca" personalizada variables pueden ser referenciadas por cualquier atributo marcado como "Sujeto a 'Variable de Make' sustitución”, pero solo en destinos que Depende de otros destinos que definen estas variables.

Como práctica recomendada, todas las variables deben ser personalizadas, a menos que haya una para integrarlos en el núcleo de Bazel. Esto evita que Bazel tenga que cargar dependencias potencialmente costosas para proporcionar variables que pueden no ser relevantes para los destinos que consumen.

Variables de cadena de herramientas de C++

Los siguientes elementos se definen en las reglas de la cadena de herramientas de C++ y están disponibles para cualquier regla que establezca toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"]. Algunas reglas, como java_binary, incluyen implícitamente la cadena de herramientas de C++ en su definición de reglas. Heredan estas variables automáticamente.

Las reglas de C++ integradas son mucho más sofisticadas que "ejecutar el compilador en ". Para admitir modos de compilación tan diversos como *SAN, ThinLTO, con o sin módulos y binarios cuidadosamente optimizados al mismo tiempo que pruebas de ejecución rápida en varias plataformas, las reglas integradas son para asegurarte de que se establezcan las entradas, salidas y marcas de línea de comandos correctas en cada una de las posibles acciones generadas internamente.

Estas variables son un mecanismo de resguardo que usarán los expertos en lenguaje en casos excepcionales. Si tienes la tentación de usarlas, primero comunícate con los desarrolladores de Bazel.

  • ABI: La versión de la ABI de C++.
  • AR: La "ar" desde el comando crosstool.
  • C_COMPILER El identificador del compilador C/C++, p.ej., llvm
  • CC: Es el comando del compilador de C y C++.

    Te recomendamos que siempre uses CC_FLAGS en combinación con CC. No lo harás bajo tu propio riesgo.

  • CC_FLAGS: Es un conjunto mínimo de marcas para C/C++. de código abierto para que pueda usarlos genrules. En particular, contiene marcas para seleccionar la arquitectura correcta si CC admite varias arquitecturas.
  • NM: Es el "nm". desde el comando crosstool.
  • OBJCOPY: Es el comando objcopy del mismo paquete que C/C++. compilador.
  • STRIP: El comando strip del mismo paquete que el compilador de C/C++.

Variables de la cadena de herramientas de Java

Los siguientes se definen en las reglas de la cadena de herramientas de Java y están disponibles para cualquier regla. que establezca toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"] (o "@bazel_tools//tools/jdk:current_host_java_runtime" para el equivalente de la cadena de herramientas del host).

La mayoría de las herramientas del JDK no deben usarse directamente. Las reglas integradas de Java usan enfoques mucho más sofisticados para la compilación y el empaquetado de Java que las herramientas upstream pueden expresar, como los archivos JAR de interfaz, los archivos JAR de interfaz de encabezado y las implementaciones de combinación y empaquetado de archivos JAR altamente optimizados.

Estas variables son un mecanismo de resguardo que usarán los expertos en lenguaje en casos excepcionales. Si sientes la tentación de usarlas, primero comunícate con los desarrolladores de Bazel.

  • JAVA: El “java” (una máquina virtual de Java máquina). Evita esto y usa una regla java_binary. en su lugar, siempre que sea posible. Puede ser una ruta de acceso relativa. Si debes cambiar directorios antes de invocar java, debes capturar el directorio de trabajo antes de cambiarlo.
  • JAVABASE: El directorio base que contiene el Utilidades de Java. Puede ser una ruta de acceso relativa. Tendrá una bandeja de entrada. subdirectorio.

Variables definidas por Starlark

Los escritores de reglas y cadenas de herramientas pueden definir variables completamente personalizadas si muestran un proveedor de TemplateVariableInfo. Cualquier regla que dependa de estas mediante la Luego, el atributo toolchains puede leer sus valores:

Consulta un ejemplo de variables definidas por Starlark.