- Usar
- Variables predefinidas
- Variables genrule predefinidas
- Variables de ruta de acceso de origen/salida predefinidas
- Variables personalizadas
Las variables "Make" son una clase especial de variables de cadena expandibles disponibles para los atributos marcados como "Sujeto a la sustitución de 'Make variable'".
Se pueden usar, por ejemplo, para insertar rutas de acceso específicas de la cadena de herramientas en acciones de compilación construidas por el usuario.
Bazel proporciona variables predefinidas, que están disponibles para todos los destinos, y variables personalizadas, que se definen en los destinos de dependencia y solo están disponibles para los destinos que dependen de ellos.
El motivo del término "Make" es histórico: la sintaxis y la semántica de estas variables se diseñaron originalmente para que coincidieran con GNU Make.
Usar
Los atributos marcados como "Sujeto a la sustitución de 'Make variable'" 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
a FOO's value. Si ese valor es "bar", la cadena final
se convierte en lo siguiente:
my_attr = "prefix bar suffix"
Si FOO no corresponde a una variable conocida por el destino de consumo, 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
@, usando solo un signo de dólar, sin
los paréntesis. Por ejemplo:
my_attr = "prefix $@ suffix"
Para escribir $ como un literal de cadena (es decir, para evitar la expansión de variables), escribe $$.
Predefined variables
Predefined "Make" variables can be referenced by any attribute marked as "Subject to 'Make variable' substitution" on any target.
To see the list of these variables and their values for a given set of build options, run
bazel info --show_make_env [build options]
and look at the top output lines with capital letters.
See an example of predefined variables.
Toolchain option variables
COMPILATION_MODE:fastbuild,dbg, oropt. (more details)
Path variables
-
BINDIR: The base of the generated binary tree for the target architecture.Note that a different tree may be used for programs that run during the build on the host architecture, to support cross-compiling.
If you want to run a tool from within a
genrule, the recommended way to get its path is$(execpath toolname), where toolname must be listed in thegenrule'stoolsattribute. GENDIR: The base of the generated code tree for the target architecture.
Machine architecture variables
-
TARGET_CPU: The target architecture's CPU, e.g.k8.
Predefined genrule variables
The following are specially available to genrule's
cmd attribute and are
generally important for making that attribute work.
See an example of predefined genrule variables.
OUTS: Thegenrule'soutslist. If you have only one output file, you can also use$@.-
SRCS: Thegenrule'ssrcslist (or more precisely: the path names of the files corresponding to labels in thesrcslist). If you have only one source file, you can also use$<. -
<:SRCS, if it is a single file. Else triggers a build error. -
@:OUTS, if it is a single file. Else triggers a build error. -
RULEDIR: The output directory of the target, that is, the directory corresponding to the name of the package containing the target under thegenfilesorbintree. For//my/pkg:my_genrulethis always ends inmy/pkg, even if//my/pkg:my_genrule's outputs are in subdirectories. -
@D: The output directory. If outs has one entry, this expands to the directory containing that file. If it has multiple entries, this expands to the package's root directory in thegenfilestree, even if all output files are in the same subdirectory!Note: Use
RULEDIRover@DbecauseRULEDIRhas simpler semantics and behaves the same way regardless of the number of output files.If the genrule needs to generate temporary intermediate files (perhaps as a result of using some other tool like a compiler), it should attempt to write them to
@D(although/tmpwill also be writable) and remove them before finishing.Especially avoid writing to directories containing inputs. They may be on read-only filesystems. Even if not, doing so would trash the source tree.
Note: If the filenames corresponding to the input labels or the output
filenames contain spaces, ', or other special characters (or your
genrule is part of a Starlark macro which downstream users may invoke on such
files), then $(SRCS) and $(OUTS) are not suitable
for interpolation into a command line, as they do not have the semantics that
"${@}" would in Bash.
One workaround is to convert to a Bash array, with
mapfile SRCS <<< "$$(sed -e 's/ /\\n/g' <<'genrule_srcs_expansion' $(SRC) genrule_srcs_expansion )y, luego, usa"$$\{SRCS[@]}"en las líneas de comandos posteriores en lugar de$(SRCS). Una opción más sólida es escribir una regla de Starlark.Variables de ruta de acceso de origen/salida predefinidas
Las variables predefinidas
execpath,execpaths,rootpath,rootpaths,location, ylocationstoman parámetros de etiqueta (p.ej.,$(execpath //foo:bar)) y sustituyen las rutas de acceso de los archivos que denota esa etiqueta.Para los archivos fuente, esta es la ruta de acceso relativa a la raíz de tu espacio de trabajo. Para 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 de acceso predefinidas.
-
execpath: Denota la ruta de acceso debajo de execroot donde Bazel ejecuta acciones de compilación.En el ejemplo anterior, Bazel ejecuta todas las acciones de compilación en el directorio vinculado por el vínculo simbólico
bazel-myprojecten la raíz de tu espacio de trabajo. El archivo fuenteempty.sourceestá vinculado en la ruta de accesobazel-myproject/testapp/empty.source. Por lo tanto, su ruta de acceso de ejecución (que es la subruta de acceso debajo de la raíz) estestapp/empty.source. Esta es la ruta de acceso que pueden usar las acciones de compilación para encontrar el archivo.Los archivos de salida se organizan de manera similar, pero también tienen el prefijo de la subruta de acceso
bazel-out/cpu-compilation_mode/bin(o para los resultados de las herramientas:bazel-out/cpu-opt-exec-hash/bin). En el ejemplo anterior,//testapp:appes una herramienta porque aparece en el atributotoolsdeshow_app_output. Por lo tanto, su archivo de salidaappse 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 CPUs diferentes en la misma compilación sin que los resultados se superpongan.La etiqueta que se pasa a esta variable debe representar exactamente un archivo. Para las etiquetas que representan archivos fuente, esto es automáticamente verdadero. Para las etiquetas que representan reglas, la regla debe generar exactamente una salida. Si esto es falso o la etiqueta no tiene el formato correcto, la compilación falla con un error.
-
rootpath: Denota la ruta de acceso que un objeto binario compilado puede usar para encontrar una dependencia en el tiempo de ejecución en relación con el subdirectorio de su directorio de archivos de ejecución que corresponde al repositorio principal. Nota: Esto solo funciona si--enable_runfilesestá habilitado, lo que no sucede en Windows de forma predeterminada. En su lugar, usarlocationpathpara la compatibilidad multiplataforma.Es similar a
execpathpero quita los prefijos de configuración que se describieron anteriormente. En el ejemplo anterior, esto significa que tantoempty.sourcecomoappusan rutas de acceso relativas al espacio de trabajo puras:testapp/empty.sourceytestapp/app.El
rootpathde un archivo en un repositorio externorepocomenzará con../repo/, seguido de la ruta de acceso relativa al repositorio.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ónRlocationde una biblioteca de archivos de ejecución para encontrar una dependencia en el tiempo de ejecución, ya sea en el directorio de archivos de ejecución (si está disponible) o con el manifiesto de archivos de ejecución.Es similar a
rootpathen el sentido de que no contiene prefijos de configuración, pero difiere en que siempre comienza con el nombre del repositorio. En el ejemplo anterior, esto significa queempty.sourceyappdan como resultado las siguientes rutas de acceso:myproject/testapp/empty.sourceymyproject/testapp/app.El
rlocationpathde un archivo en un repositorio externorepocomenzará conrepo/, seguido de la ruta de acceso relativa al repositorio.Pasar esta ruta de acceso a un objeto binario y resolverla en una ruta de acceso del sistema de archivos con las bibliotecas de archivos de ejecución es el enfoque preferido para encontrar dependencias en el tiempo de ejecución. En comparación con
rootpath, tiene la ventaja de que funciona en todas las plataformas, incluso si el directorio de archivos de ejecución no está disponible.Tiene los mismos requisitos de "una sola salida" que
execpath. -
location: Es un sinónimo deexecpathorootpath, según el atributo que se expanda. Este es comportamiento heredado anterior a Starlark y no se recomienda, a menos que sepas lo que hace para una regla en particular. Consulta #2475 para obtener más detalles.
execpaths, rootpaths, rlocationpaths,
y locations son las variaciones plurales de execpath,
rootpath, rlocationpath, ylocation,
respectivamente. Admiten etiquetas que producen varias salidas, en cuyo caso
cada salida se muestra separada por un espacio. Las reglas de salida cero y las etiquetas con formato incorrecto
producen errores de compilación.
Todas las etiquetas a las que se hace referencia deben aparecer en srcs, los archivos de salida
o deps. De lo contrario, la compilación falla. Los destinos de C++ también pueden hacer referencia a etiquetas en data.
Las etiquetas no tienen que estar en formato canónico: foo, :foo
y //somepkg:foo están bien.
Variables personalizadas
Se puede hacer referencia a las variables "Make" personalizadas con cualquier atributo marcado como "Sujeto a la sustitución de 'Make variable'", pero solo en los destinos que dependen de otros destinos que definen estas variables.
Como práctica recomendada, todas las variables deben ser personalizadas, a menos que haya un motivo muy bueno para incorporarlas a Bazel principal. Esto evita que Bazel tenga que cargar dependencias potencialmente costosas para proporcionar variables que los destinos de consumo no puedan usar.
Variables de la cadena de herramientas de C++
Las siguientes 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:toolchain_type"]
Algunas reglas, como java_binary, incluyen implícitamente
la cadena de herramientas de C++ en su definición de regla. Heredan estas variables
automáticamente.
Las reglas integradas de C++ son mucho más sofisticadas que "ejecutar el compilador en ellas". Para admitir modos de compilación tan diversos como *SAN, ThinLTO, con o sin módulos, y objetos binarios cuidadosamente optimizados al mismo tiempo que pruebas de ejecución rápida en varias plataformas, las reglas integradas hacen todo lo posible para garantizar que se establezcan las entradas, las salidas y las marcas de línea de comandos correctas en cada una de las acciones generadas internamente.
Estas variables son un mecanismo de resguardo que los expertos en lenguajes pueden usar en casos excepcionales. Si tienes la tentación de usarlas, comunícate primero con los desarrolladores de Bazel.
ABI: La versión de ABI de C++.-
AR: El comando "ar" de crosstool. -
C_COMPILER: El identificador del compilador de C/C++, p.ej.,llvm. -
CC: El comando del compilador de C y C++.Te recomendamos que siempre uses
CC_FLAGSen combinación conCC. Si no lo haces, será bajo tu propio riesgo. CC_FLAGS: Un conjunto mínimo de marcas para que el compilador de C/C++ pueda usar genrules. En particular, contiene marcas para seleccionar la arquitectura correcta siCCadmite varias arquitecturas.-
DUMPBIN: El volcado de archivos binarios COFF de Microsoft (dumpbin.exe) de Microsoft Visual Studio. -
NM: El comando "nm" de crosstool. -
OBJCOPY: El comando objcopy del mismo paquete que el compilador de C/C++ -
STRIP: El comando strip del mismo paquete que el compilador de C/C++
Variables de la cadena de herramientas de Java
Las siguientes se definen en las reglas de la cadena de herramientas de Java y están disponibles para cualquier regla
que establezca toolchains =
["@rules_java//toolchains:current_java_runtime"] (o
"@rules_java//toolchains:current_host_java_runtime"
para el equivalente de la cadena de herramientas del host).
No se debe usar directamente la mayoría de las herramientas del JDK. Las reglas integradas de Java usan enfoques mucho más sofisticados para la compilación y el empaquetado de Java que las herramientas ascendentes pueden expresar, como los Jars de interfaz, los Jars de interfaz de encabezado y las implementaciones de empaquetado y combinación de Jars altamente optimizadas.
Estas variables son un mecanismo de resguardo que los expertos en lenguajes pueden usar en casos excepcionales. Si tienes la tentación de usarlas, comunícate primero con los desarrolladores de Bazel.
-
JAVA: El comando "java" (una máquina virtual de Java ). Evita esto y usa una reglajava_binaryen su lugar siempre que sea posible. Puede ser una ruta de acceso relativa. Si debes cambiar directorios 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 "bin" subdirectorio.
Variables definidas por Starlark
Los escritores de reglas y cadenas de herramientas pueden definir
variables completamente personalizadas si muestran un
TemplateVariableInfo. Cualquier regla que dependa de estas a través del
toolchains atributo puede leer sus valores: