- Uso
- Variables predefinidas
- Variables predefinidas de Genrule
- Variables predefinidas de la ruta de fuente/salida
- Variables personalizadas
Las variables "Make" son una clase especial de variables de string expandibles disponibles para los atributos marcados como "Subject to 'Make variable' overlay".
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 los objetivos de dependencia y solo están disponibles para los destinos que dependen de ellas.
El término "Make" se debe a que es histórico: la sintaxis y la semántica de estas variables se pretendían originalmente para coincidir con GNU Make.
Uso
Los atributos marcados como "Subject to 'Make variable' Python' pueden hacer referencia a la variable "Make" FOO
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"
, la última string se convierte en lo siguiente:
my_attr = "prefix bar suffix"
Si FOO
no corresponde a una variable conocida por el destino que consume, Bazel falla con un error.
También se puede hacer referencia a las variables "Make" cuyos nombres son símbolos que no son letras, como @
, con solo un signo de dólar, sin los paréntesis. Por ejemplo:
my_attr = "prefix $@ suffix"
Para escribir $
como un literal de string (es decir, para evitar la expansión de variables), escribe $$
.
Variables predefinidas
Cualquier atributo marcado como “Sujeto a “Sustitución de variables”, que se encuentra sujeta a cualquier destino, puede hacer referencia a las variables “Marca” predefinidas.
Para ver la lista de estas variables y sus valores para un conjunto determinado de opciones de compilación, ejecuta lo siguiente:
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
COMPILATION_MODE
:fastbuild
,dbg
oopt
. (Más detalles)
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 host para admitir la compilación cruzada.
Si deseas ejecutar una herramienta desde un
genrule
, la forma recomendada de obtener su ruta de acceso es$(execpath toolname)
, donde toolname debe aparecer en el atributotools
degenrule
. GENDIR
: Es la base del árbol de código generado para la arquitectura de destino.
Variables de arquitectura de máquina
-
TARGET_CPU
: Es la CPU de la arquitectura de destino, p.ej.,k8
.
Variables predefinidas de Genrule
Los siguientes elementos están especialmente disponibles para el atributo cmd
de genrule
y, en general, son importantes para hacer que ese atributo funcione.
Consulta un ejemplo de variables de genrule predefinidas.
OUTS
: Es la listaouts
degenrule
. Si solo tienes un archivo de salida, también puedes usar$@
.-
SRCS
: Es la listasrcs
degenrule
(o, más precisamente, los nombres de ruta de los archivos que corresponden a las etiquetas de la listasrcs
). Si solo tienes un archivo fuente, también puedes usar$<
. -
<
:SRCS
, si es un archivo único De lo contrario, se activa un error de compilación. -
@
:OUTS
, si es un archivo único De lo contrario, se activa un error de compilación. -
RULEDIR
: Es el directorio de salida del destino, es decir, el directorio correspondiente al nombre del paquete que contiene el destino en los árbolesgenfiles
obin
. Para//my/pkg:my_genrule
, esto siempre termina enmy/pkg
, incluso si las salidas de//my/pkg:my_genrule
están en subdirectorios. -
@D
: Es el directorio de salida. Si outs tiene una entrada, se expande al directorio que contiene ese archivo. Si tiene varias entradas, se expande al directorio raíz del paquete en el árbolgenfiles
, incluso si todos los archivos de salida están en el mismo subdirectorio.Nota: Usa
RULEDIR
en lugar de@D
, ya queRULEDIR
tiene una semántica más simple y se comporta de la misma manera, independientemente de la cantidad de archivos de salida.Si genrule necesita generar archivos intermedios temporales (por ejemplo, como resultado del uso de alguna otra herramienta, como un compilador), debería intentar escribirlos en
@D
(aunque/tmp
también se podrá escribir) y quitarlos antes de finalizar.En especial, evita escribir en directorios que contengan entradas. Pueden estar en sistemas de archivos de solo lectura. Incluso si no lo hiciste, el árbol de fuentes se eliminaría.
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 al archivo indicadas por esa etiqueta.
Para los archivos de origen, es la ruta de acceso relativa a la raíz de tu lugar de trabajo. Para los archivos que son resultados de reglas, esta es la ruta de salida del archivo (consulta la explicación de archivos de salida más abajo).
Consulta un ejemplo de variables de ruta de acceso predefinidas.
-
execpath
: Denota la ruta debajo de 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 por el symlink
bazel-myproject
en la raíz de tu espacio de trabajo. El archivo de origenempty.source
está vinculado en la rutabazel-myproject/testapp/empty.source
. Por lo tanto, su ruta de acceso de ejecución (que es la ruta secundaria debajo de la raíz) estestapp/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
bazel-out/cpu-compilation_mode/bin
de la ruta secundaria (obazel-out/cpu-opt-exec-hash/bin
para las salidas de las herramientas). En el ejemplo anterior,//testapp:app
es una herramienta porque aparece en el atributotools
deshow_app_output
. Por lo tanto, su archivo de salidaapp
se escribe enbazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app
. Por lo tanto, la ruta de acceso de ejecución esbazel-out/cpu-opt-exec-hash/bin/testapp/app
. Este prefijo adicional permite compilar el mismo destino para, por ejemplo, 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 automáticamente verdadero. En el caso de las etiquetas que representan reglas, la regla debe generar exactamente un resultado. Si esto es falso o la etiqueta presenta errores de formato, la compilación fallará con un error.
-
rootpath
: Indica la ruta de acceso que un objeto binario compilado puede usar para encontrar una dependencia en el entorno de ejecución en relación con el subdirectorio de su directorio de archivos de ejecución correspondiente al repositorio principal. Nota: Esta opción solo funciona si está habilitada--enable_runfiles
, que no es el caso de Windows de forma predeterminada. Usarlocationpath
en su lugar para la compatibilidad multiplataforma.Es similar a
execpath
, pero quita los prefijos de configuración descritos anteriormente. En el ejemplo anterior, esto significa queempty.source
yapp
usan rutas de acceso relativas puras del espacio de trabajo:testapp/empty.source
ytestapp/app
.El
rootpath
de un archivo en unrepo
de repositorio externo comenzará con../repo/
, seguido de la ruta de acceso relativa del repositorio.Esto tiene los mismos requisitos de "una sola salida" que
execpath
. -
rlocationpath
: Es la ruta de acceso que un objeto binario compilado puede pasar a la funciónRlocation
de una biblioteca de runfiles para encontrar una dependencia en el entorno de ejecución, ya sea en el directorio runfiles (si está disponible) o mediante el manifiesto de runfiles.Esto es similar a
rootpath
, ya que no contiene prefijos de configuración, pero se diferencia en que siempre comienza con el nombre del repositorio. En el ejemplo anterior, esto significa queempty.source
yapp
dan como resultado las siguientes rutas de acceso:myproject/testapp/empty.source
ymyproject/testapp/app
.El
rlocationpath
de un archivo en unrepo
de repositorio externo comenzará conrepo/
, seguido de la ruta de acceso relativa del repositorio.Pasar esta ruta de acceso a un objeto binario y resolverlo en una ruta del sistema de archivos con las bibliotecas de archivos de ejecución es el enfoque preferido para encontrar dependencias en el entorno de ejecución. En comparación con
rootpath
, tiene la ventaja de que funciona en todas las plataformas, incluso si el directorio runfiles no está disponible.Esto tiene los mismos requisitos de "una sola salida" que
execpath
. -
location
: Es un sinónimo deexecpath
orootpath
, según el atributo que se expande. Este es un comportamiento heredado previo a Starlark y no se recomienda, a menos que realmente sepas lo que hace para una regla en particular. Consulta #2475 para obtener más detalles.
execpaths
, rootpaths
, rlocationpaths
y locations
son las variaciones en plural de execpath
, rootpath
, rlocationpaths
y location
, respectivamente. Admiten etiquetas que producen varias salidas, en cuyo caso cada salida se enumera por separado por un espacio. Las reglas sin salida y las etiquetas con formato incorrecto
generan errores de compilación.
Todas las etiquetas a las que se hace referencia deben aparecer en el srcs
, los archivos de salida o deps
del destino de consumo. De lo contrario, la compilación falla. Los destinos de C++ también pueden hacer referencia a etiquetas en data
.
No es necesario que las etiquetas estén en su formato canónico: foo
, :foo
y //somepkg:foo
están bien.
Variables personalizadas
Cualquier atributo marcado como "Subject to 'Make variable' Linux" puede hacer referencia a las variables personalizadas, pero solo en objetivos que dependen de otros destinos que definen estas variables.
Como práctica recomendada, todas las variables deben ser personalizadas, a menos que haya un buen motivo para integrarlas en el núcleo de Bazel. Esto evita que Bazel tenga que cargar dependencias potencialmente costosas para suministrar variables que consuman tarets y que podrían no interesarles.
Variables de la 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. Estas variables se heredan automáticamente.
Las reglas de C++ integradas son mucho más sofisticadas que "ejecutar el compilador en ella". Para admitir modos de compilación tan diversos como *SAN, ThinLTO, con o sin módulos y objetos binarios cuidadosamente optimizados y al mismo tiempo que las pruebas de ejecución rápida en varias plataformas, las reglas integradas se esfuerzan mucho para garantizar que las entradas, las salidas y las marcas de línea de comandos correctas estén configuradas 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 sientes la tentación de usarlas, primero comunícate con los desarrolladores de Bazel.
ABI
: Es la versión de ABI de C++.-
AR
: Es el comando "ar" del crosstool. -
C_COMPILER
: Es el identificador del compilador C/C++, p.ej.,llvm
. -
CC
: Es el comando del compilador C y C++.Te recomendamos que siempre uses
CC_FLAGS
junto conCC
. No lo harás bajo tu propio riesgo. CC_FLAGS
: Es un conjunto mínimo de marcas para que las genrules puedan usar el compilador C/C++. En particular, contiene marcas para seleccionar la arquitectura correcta siCC
admite varias arquitecturas.-
NM
: Es el comando "nm" del crosstool. -
OBJCOPY
: Es el comando objcopy del mismo paquete que el compilador C/C++. -
STRIP
: Es el comando de eliminación del mismo paquete que el compilador C/C++.
Variables de la cadena de herramientas de Java
Los siguientes elementos 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 de host).
La mayoría de las herramientas del JDK no deben usarse directamente. Las reglas integradas de Java usan enfoques mucho más sofisticados de la compilación y el empaquetado de Java que las herramientas upstream pueden expresar, como los jarras de interfaz, los de interfaz de encabezado y las implementaciones de combinación y empaquetado altamente optimizadas de jar.
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
: Es el comando “java” (una máquina virtual de Java). Evita esto y usa una reglajava_binary
cuando sea posible. Puede ser una ruta de acceso relativa. Si debes cambiar de directorio antes de invocarjava
, debes capturar el directorio de trabajo antes de cambiarlo. JAVABASE
: El directorio base que contiene las utilidades de Java. Puede ser una ruta de acceso relativa. Tendrá un subdirectorio "bin".
Variables definidas por Starlark
Los escritores de reglas y cadenas de herramientas pueden definir variables completamente personalizadas si muestran un proveedor TemplateVariableInfo. Cualquier regla que dependa de estas a través del atributo toolchains
puede leer sus valores: