Bazel tiene compatibilidad sofisticada para modelar plataformas y cadenas de herramientas para compilaciones de varias arquitecturas y compilaciones cruzadas.
En esta página, se resume el estado de esta compatibilidad.
Consulta lo siguiente:
Estado
C++
Las reglas de C++ usan plataformas para seleccionar cadenas de herramientas cuando se establece --incompatible_enable_cc_toolchain_resolution.
Esto significa que puedes configurar un proyecto de C++ con lo siguiente:
bazel build //:my_cpp_project --platforms=//:myplatformen lugar de lo heredado:
bazel build //:my_cpp_project` --cpu=... --crosstool_top=... --compiler=...Se habilitará de forma predeterminada en Bazel 7.0 (#7260).
Para probar tu proyecto de C++ con plataformas, consulta Migra tu proyecto y Configura cadenas de herramientas de C++.
Java
Las reglas de Java usan plataformas para seleccionar cadenas de herramientas.
Esto reemplaza las marcas heredadas --java_toolchain, --host_java_toolchain, --javabase y --host_javabase.
Consulta Java y Bazel para obtener más detalles.
Android
Las reglas de Android usan plataformas para seleccionar cadenas de herramientas cuando se establece --incompatible_enable_android_toolchain_resolution.
Esto significa que puedes configurar un proyecto de Android con lo siguiente:
bazel build //:my_android_project --android_platforms=//:my_android_platformen lugar de con marcas heredadas como --android_crosstool_top, --android_cpu,
y --fat_apk_cpu.
Se habilitará de forma predeterminada en Bazel 7.0 (#16285).
Para probar tu proyecto de Android con plataformas, consulta Migra tu proyecto.
Apple
Las reglas de Apple no admiten plataformas y aún no están programadas para la compatibilidad.
Aún puedes usar las APIs de plataforma con compilaciones de Apple (por ejemplo, cuando compilas con una combinación de reglas de Apple y C++ puro) con asignaciones de plataforma.
Otros idiomas
- Las reglas de Go admiten plataformas por completo.
- Las reglas de Rust admiten plataformas por completo.
Si tienes un conjunto de reglas de idioma, consulta Migra tu conjunto de reglas para agregar compatibilidad.
Información general
Se introdujeron plataformas y cadenas de herramientas para estandarizar la forma en que los proyectos de software se orientan a diferentes arquitecturas y se compilan de forma cruzada.
Esto se
inspiró
en la observación de que los mantenedores de idiomas ya lo hacían de formas ad
hoc e incompatibles. Por ejemplo, las reglas de C++ usaban --cpu y
--crosstool_top para declarar una CPU y una cadena de herramientas de destino. Ninguno de estos modela correctamente una "plataforma". Esto produjo compilaciones incómodas e incorrectas.
Java, Android y otros idiomas desarrollaron sus propias marcas para propósitos similares, ninguna de las cuales interoperaba entre sí. Esto hizo que las compilaciones de varios idiomas fueran confusas y complicadas.
Bazel está diseñado para proyectos grandes, de varios idiomas y de varias plataformas. Esto exige una compatibilidad más fundamentada para estos conceptos, incluida una API estándar clara.
Necesidad de migración
La actualización a la nueva API requiere dos esfuerzos: lanzar la API y actualizar la lógica de reglas para usarla.
El primero ya se realizó, pero el segundo está en curso. Esto consiste en garantizar que se definan las plataformas y las cadenas de herramientas específicas del idioma, que la lógica del idioma lea las cadenas de herramientas a través de la nueva API en lugar de marcas antiguas como --crosstool_top y que config_settings seleccione en la nueva API en lugar de marcas antiguas.
Este trabajo es sencillo, pero requiere un esfuerzo distinto para cada idioma, además de una advertencia justa para que los propietarios del proyecto realicen pruebas en función de los próximos cambios.
Por eso, esta es una migración en curso.
Objetivo
Esta migración se completa cuando todos los proyectos se compilan con el formulario:
bazel build //:myproject --platforms=//:myplatformEsto implica lo siguiente:
- Las reglas de tu proyecto eligen las cadenas de herramientas adecuadas para
//:myplatform. - Las dependencias de tu proyecto eligen las cadenas de herramientas adecuadas para
//:myplatform. //:myplatformhace referencia a declaraciones comunes deCPU,OSy otras propiedades genéricas independientes del idioma.- Todas las
select()s pertinentes coinciden correctamente con//:myplatform. //:myplatformse define en un lugar claro y accesible: en el repositorio de tu proyecto si la plataforma es exclusiva de tu proyecto o en un lugar común donde todos los proyectos que consumen pueden encontrarla.
Las marcas antiguas como --cpu, --crosstool_top y --fat_apk_cpu dejarán de estar disponibles y se quitarán tan pronto como sea seguro hacerlo.
En última instancia, esta será la única forma de configurar arquitecturas.
Migra tu proyecto
Si compilas con idiomas que admiten plataformas, tu compilación ya debería funcionar con una invocación como la siguiente:
bazel build //:myproject --platforms=//:myplatformConsulta Estado y la documentación de tu idioma para obtener detalles precisos.
Si un idioma requiere una marca para habilitar la compatibilidad con la plataforma, también debes establecer esa marca. Consulta Estado para obtener más información.
Para que se compile tu proyecto, debes verificar lo siguiente:
Debe existir
//:myplatform. Por lo general, es responsabilidad del propietario del proyecto definir plataformas, ya que los diferentes proyectos se orientan a diferentes máquinas. Consulta Plataformas predeterminadas.Deben existir las cadenas de herramientas que deseas usar. Si usas cadenas de herramientas de stock, los propietarios del idioma deben incluir instrucciones para registrarlas. Si escribes tus propias cadenas de herramientas personalizadas, debes registrarlas en tu
MODULE.bazelarchivo o con--extra_toolchains.Las
select()y las transiciones de configuración deben resolverse correctamente. Consulta select() y Transiciones.Si tu compilación combina idiomas que admiten y no admiten plataformas, es posible que necesites asignaciones de plataforma para ayudar a que los idiomas heredados funcionen con la nueva API. Consulta Asignaciones de plataforma para obtener más detalles.
Si los problemas persisten, comunícate con el equipo de asistencia.
Plataformas predeterminadas
Los propietarios del proyecto deben definir plataformas explícitas
para describir las arquitecturas
para las que desean compilar. Luego, se activan con --platforms.
Cuando no se establece --platforms, Bazel usa de forma predeterminada un platform que representa la
máquina de compilación local. Se genera automáticamente en @platforms//host (con el alias @bazel_tools//tools:host_platform), por lo que no es necesario definirlo de forma explícita. Asigna OS
y CPU de la máquina local con constraint_values declarados en
@platforms.
select()
Los proyectos pueden select() en
constraint_value objetivos pero no en plataformas
completas. Esto es intencional, por lo que select() admite la mayor variedad posible de máquinas. Una biblioteca con fuentes específicas de ARM debe admitir todas las máquinas con tecnología ARM, a menos que haya motivos para ser más específicos.
Para seleccionar una o más constraint_values, usa lo siguiente:
config_setting(
name = "is_arm",
constraint_values = [
"@platforms//cpu:arm",
],
)
Esto equivale a seleccionar tradicionalmente en --cpu:
config_setting(
name = "is_arm",
values = {
"cpu": "arm",
},
)
Obtén más detalles aquí.
Las select en --cpu, --crosstool_top, etcétera, no comprenden --platforms.
Cuando migres tu proyecto a plataformas, debes convertirlas en
constraint_values o usar asignaciones de plataforma para admitir
ambos estilos durante la migración.
Transiciones
Las transiciones de Starlark cambian
las marcas en partes de tu gráfico de compilación. Si tu proyecto usa una transición que establece --cpu, --crossstool_top o cualquier otra marca heredada, las reglas que leen --platforms no verán estos cambios.
Cuando migres tu proyecto a plataformas, debes convertir los cambios como
return { "//command_line_option:cpu": "arm" } a return {
"//command_line_option:platforms": "//:my_arm_platform" } o usar asignaciones de
plataforma para admitir ambos estilos durante la migración.
ventana.
Migra tu conjunto de reglas
Si tienes un conjunto de reglas y deseas admitir plataformas, debes hacer lo siguiente:
Haz que la lógica de reglas resuelva las cadenas de herramientas con la API de cadena de herramientas. Consulta la API de cadena de herramientas (
ctx.toolchains).Opcional: Define una marca
--incompatible_enable_platforms_for_my_languagepara que la lógica de reglas resuelva cadenas de herramientas de forma alternativa a través de la nueva API o marcas antiguas como--crosstool_topdurante las pruebas de migración.Define las propiedades relevantes que componen los componentes de la plataforma. Consulta Propiedades comunes de la plataforma.
Define cadenas de herramientas estándar y haz que los usuarios puedan acceder a ellas a través de las instrucciones de registro de tu regla (detalles)
Asegúrate de que las
select()s y las transiciones de configuración admitan plataformas. Este es el mayor desafío. Es particularmente desafiante para proyectos de varios idiomas (que pueden fallar si todos los idiomas no pueden leer--platforms).
Si necesitas combinar con reglas que no admiten plataformas, es posible que necesites asignaciones de plataforma para cerrar la brecha.
Propiedades comunes de la plataforma
Las propiedades comunes de la plataforma entre idiomas, como OS y CPU, deben
declararse en @platforms.
Esto fomenta el uso compartido, la estandarización y la compatibilidad entre idiomas.
Las propiedades exclusivas de tus reglas deben declararse en el repositorio de tu regla. Esto te permite mantener una propiedad clara sobre los conceptos específicos de los que son responsables tus reglas.
Si tus reglas usan SO o CPUs de propósito personalizado, estos deben declararse en el
repositorio de tu regla en comparación con
@platforms.
Asignaciones de plataforma
Las asignaciones de plataforma son una API temporal que permite que la lógica compatible con la plataforma se combine con la lógica heredada en la misma compilación. Esta es una herramienta directa que solo está diseñada para suavizar las incompatibilidades con diferentes plazos de migración.
Una asignación de plataforma es un mapa de una platform() a un conjunto correspondiente de marcas heredadas o al revés. Por ejemplo:
platforms:
# Maps "--platforms=//platforms:ios" to "--ios_multi_cpus=x86_64 --apple_platform_type=ios".
//platforms:ios
--ios_multi_cpus=x86_64
--apple_platform_type=ios
flags:
# Maps "--ios_multi_cpus=x86_64 --apple_platform_type=ios" to "--platforms=//platforms:ios".
--ios_multi_cpus=x86_64
--apple_platform_type=ios
//platforms:ios
# Maps "--cpu=darwin_x86_64 --apple_platform_type=macos" to "//platform:macos".
--cpu=darwin_x86_64
--apple_platform_type=macos
//platforms:macos
Bazel usa esto para garantizar que todos los parámetros de configuración, tanto los basados en la plataforma como los heredados, se apliquen de manera coherente en toda la compilación, incluso a través de las transiciones.
De forma predeterminada, Bazel lee asignaciones del archivo platform_mappings en la raíz de tu espacio de trabajo. También puedes establecer --platform_mappings=//:my_custom_mapping.
Consulta el diseño de las asignaciones de plataforma para obtener más detalles.
Revisión de la API
Un platform es una colección de
constraint_value objetivos:
platform(
name = "myplatform",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:arm",
],
)
Una constraint_value es una propiedad
de la máquina. Los valores del mismo "tipo" se agrupan en un
constraint_setting común:
constraint_setting(name = "os")
constraint_value(
name = "linux",
constraint_setting = ":os",
)
constraint_value(
name = "mac",
constraint_setting = ":os",
)
Un toolchain es una regla de Starlark. Sus
atributos declaran las herramientas de un idioma (como compiler =
"//mytoolchain:custom_gcc"). Sus proveedores pasan
esta información a las reglas que deben compilarse con estas herramientas.
Las cadenas de herramientas declaran los constraint_values de las máquinas a las que pueden
orientarse
(target_compatible_with = ["@platforms//os:linux"]) y las máquinas en las que se pueden
ejecutar sus herramientas
(exec_compatible_with = ["@platforms//os:mac"]).
Cuando compilas $ bazel build //:myproject --platforms=//:myplatform, Bazel
selecciona automáticamente una cadena de herramientas que se puede ejecutar en la máquina de compilación y
compilar objetos binarios para //:myplatform. Esto se conoce como resolución de cadena de herramientas.
El conjunto de cadenas de herramientas disponibles se puede registrar en el MODULE.bazel archivo
con register_toolchains o en la
línea de comandos con --extra_toolchains.
Para obtener más información, haga clic aquí.
Preguntas
Si tienes preguntas o necesitas asistencia general sobre el cronograma de migración, comunícate con bazel-discuss o los propietarios de las reglas correspondientes.
Para obtener información sobre el diseño y la evolución de las APIs de plataforma o cadena de herramientas, comunícate con bazel-dev.