Migración a plataformas

Informar un problema . Ver fuente . . Por la noche · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

Bazel ofrece una asistencia sofisticada para el modelado. plataformas y cadenas de herramientas para arquitecturas compilaciones compiladas de forma cruzada.

En esta página, se resume el estado de esta compatibilidad.

Consulta lo siguiente:

Estado

C++

Las reglas C++ usan plataformas para seleccionar cadenas de herramientas cuando Se estableció --incompatible_enable_cc_toolchain_resolution.

Esto significa que puedes configurar un proyecto de C++ con lo siguiente:

bazel build //:my_cpp_project --platforms=//:myplatform

en lugar de la heredada:

bazel build //:my_cpp_project` --cpu=... --crosstool_top=...  --compiler=...

Esta opción estará habilitada de forma predeterminada en Bazel 7.0 (#7260).

Para probar tu proyecto de C++ con plataformas, consulta Cómo migrar tu proyecto y Configura cadenas de herramientas de C++.

Java

Las reglas de Java usan plataformas para seleccionar cadenas de herramientas.

Esto reemplaza a las marcas heredadas --java_toolchain, --host_java_toolchain, --javabase y --host_javabase.

Para obtener más información, consulta Java y Bazel.

Android

Las reglas de Android usan plataformas para seleccionar cadenas de herramientas cuando Se estableció --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_platform

en lugar de hacerlo con marcas heredadas, como --android_crosstool_top, --android_cpu, y --fat_apk_cpu.

Esta opción estará habilitada 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 son compatibles con las plataformas y aún no están programadas. para obtener asistencia.

Puedes seguir usando las APIs de la plataforma con compilaciones de Apple (por ejemplo, cuando compilas con una combinación de reglas de Apple y C++ puro) con la plataforma mapeos.

Otros idiomas

  • Las reglas de Go son totalmente compatibles con las plataformas.
  • Las reglas de Rust son totalmente compatibles con las plataformas.

Si tienes un conjunto de reglas de idioma, consulta Cómo migrar tu conjunto de reglas para agregar y asistencia.

Información general

Se introdujeron las plataformas y las cadenas de herramientas para estandarizar la forma en que el software los proyectos se orientan a diferentes arquitecturas y se compilan de forma cruzada.

Este era inspirado por la observación de que quienes mantienen el idioma ya estaban haciendo esto en el anuncio 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. Ninguna de estas opciones modela correctamente una "plataforma". Esto generó compilaciones incorrectas e incómodas.

Java, Android y otros lenguajes desarrollaron sus propias marcas con fines similares, ninguna de las cuales interoperaba entre sí. Esto hizo que las compilaciones entre lenguajes confusas y complicadas.

Bazel está diseñado para proyectos grandes multilingües y multiplataforma. Esta demanda más apoyo de principios para estos conceptos, lo que incluye API estándar.

Necesidad de migración

La actualización a la nueva API requiere dos esfuerzos: lanzar la API y actualizar lógica de regla para usarlo.

La primera está lista, pero la segunda sigue en curso. Esto consiste en garantizar Se definen plataformas y cadenas de herramientas específicas del lenguaje, se lee la lógica del lenguaje cadenas de herramientas a través de la API nueva en lugar de marcas antiguas, como --crosstool_top. Los elementos config_setting seleccionan la API nueva en lugar de las marcas anteriores.

Este trabajo es sencillo, pero requiere un esfuerzo distinto para cada idioma, además de una advertencia justa para que los propietarios de proyectos prueben 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 siguiente formato:

bazel build //:myproject --platforms=//:myplatform

Esto implica lo siguiente:

  1. Las reglas de tu proyecto eligen las cadenas de herramientas correctas para //:myplatform.
  2. Las dependencias de tu proyecto eligen las cadenas de herramientas correctas para //:myplatform.
  3. //:myplatform referencias declaraciones comunes de CPU, OS y otras propiedades genéricas independientes del lenguaje
  4. Todos los elementos select() relevantes coinciden correctamente con //:myplatform.
  5. //:myplatform se define en un lugar claro y accesible: en el entorno de si la plataforma es única para tu proyecto, o algo común en los proyectos que consumen muchos recursos,

Se mostrarán marcas antiguas, como --cpu, --crosstool_top y --fat_apk_cpu, que se da de baja y se quitan en cuanto sea seguro hacerlo.

En última instancia, esta será la única manera de configurar las arquitecturas.

Cómo migrar tu proyecto

Si compilas con lenguajes compatibles con plataformas, tu compilación ya debería funcionan con una invocación como esta:

bazel build //:myproject --platforms=//:myplatform

Consulta Estado y la documentación de tu lenguaje 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 tu proyecto se compile, debes verificar lo siguiente:

  1. //:myplatform debe existir. Por lo general, es responsabilidad del propietario del proyecto para definir plataformas, ya que los diferentes proyectos se orientan a máquinas distintas. Consulta Plataformas predeterminadas.

  2. Las cadenas de herramientas que deseas usar deben existir. Si usas cadenas de herramientas de archivo, los propietarios de idiomas deben incluir instrucciones sobre cómo registrarlos. Si escribiendo tus propias cadenas de herramientas personalizadas, debes registrarlas en tu Archivo MODULE.bazel o con --extra_toolchains.

  3. Las select() y las transiciones de configuración deben resolver correctamente. Consulta select() y Transiciones.

  4. Si tu compilación combina lenguajes que son compatibles y no compatibles con las plataformas, puedes Necesitamos asignaciones de plataforma para ayudar a que los idiomas heredados funcionen con la nueva API. Consulta Asignaciones de plataformas para obtener más detalles.

Si los problemas persisten, comunícate para obtener asistencia.

Plataformas predeterminadas

Los propietarios del proyecto deben definir platforms para describir las arquitecturas para los que quieren trabajar. Luego, se activan con --platforms.

Cuando --platforms no está configurado, Bazel usa de forma predeterminada una platform que representa el máquina de compilación local. Se genera automáticamente en @platforms//host (con alias como @bazel_tools//tools:host_platform) por lo que no es necesario definirla explícitamente. Asigna el OS de la máquina local. y CPU con constraint_value declarados en @platforms

select()

Los proyectos pueden select() en Destinos constraint_value pero no completo y plataformas de Google Cloud. Esto es intencional, por lo que select() admite una gran variedad de las máquinas de la nube tantos como sea posible. Una biblioteca con fuentes específicas de ARM debería admitir todos Máquinas impulsadas por ARM, a menos que haya motivos para ser más específicos.

Para seleccionar uno o más elementos constraint_value, usa lo siguiente:

config_setting(
    name = "is_arm",
    constraint_values = [
        "@platforms//cpu:arm",
    ],
)

Esto equivale a seleccionar de forma tradicional en --cpu:

config_setting(
    name = "is_arm",
    values = {
        "cpu": "arm",
    },
)

Obtén más detalles aquí.

Los elementos select en --cpu, --crosstool_top, etc. no comprenden --platforms. Cuando migres tu proyecto a plataformas, debes convertirlos a constraint_values o usa asignaciones de plataforma para admitir ambos estilos durante la migración.

Transiciones

Cambio de las transiciones de Starlark te permite marcar partes del gráfico de compilación. Si en tu proyecto se usa una transición que Configura --cpu, --crossstool_top, o bien otras marcas heredadas, reglas que leen --platforms no verá estos cambios.

Cuando migres tu proyecto a plataformas, debes convertir los cambios como return { "//command_line_option:cpu": "arm" } para return { "//command_line_option:platforms": "//:my_arm_platform" } o usa la plataforma asignaciones para admitir ambos estilos durante la migración. en la ventana modal.

Migra tu conjunto de reglas

Si tienes un conjunto de reglas y quieres admitir plataformas, debes hacer lo siguiente:

  1. Haz que la lógica de las reglas resuelva las cadenas de herramientas con la API de la cadena de herramientas. Consulta API de la cadena de herramientas (ctx.toolchains).

  2. Opcional: define una marca --incompatible_enable_platforms_for_my_language para La lógica de las reglas resuelve de manera alternativa cadenas de herramientas a través de la API nueva o las marcas anteriores. como --crosstool_top durante las pruebas de migración.

  3. Define las propiedades relevantes que conforman los componentes de la plataforma. Consulta Propiedades comunes de la plataforma

  4. Define cadenas de herramientas estándar y haz que los usuarios puedan acceder a ellas a través de tus instrucciones de registro de la regla (detalles)

  5. Asegúrate de que los select() y las transiciones de configuración admiten plataformas. Este es el mayor desafío. Es particularmente desafiante para los proyectos multilingües (que puede fallar si todos los idiomas no pueden leer --platforms).

Si necesitas combinar reglas que no son compatibles con plataformas, es posible que debas asignaciones de plataformas para cerrar la brecha.

Propiedades comunes de la plataforma

Las propiedades comunes de plataforma en varios lenguajes, como OS y CPU, deben declarado en @platforms. Esto fomenta el uso compartido, la estandarización y la compatibilidad entre lenguajes.

Las propiedades exclusivas de tus reglas se deben declarar en el repositorio de estas. Esta le permite mantener una propiedad clara sobre los conceptos específicos que se aplican a sus reglas responsable.

Si tus reglas usan SO o CPU con fines personalizados, debes declararlos en tu el repo de la regla vs. @platforms

Asignaciones de plataformas

Las asignaciones de plataforma son una API temporal que permite combinar la lógica adaptada a la plataforma con lógica heredada en la misma compilación. Esta es una herramienta contundente incompatibilidades uniformes con diferentes plazos de migración.

Una asignación de plataforma es un mapa de un platform() a un conjunto correspondiente de marcas heredadas o viceversa. 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 toda la configuración, tanto basada en la plataforma como heredadas, se aplican de forma coherente en toda la compilación, incluso mediante transiciones.

De forma predeterminada, Bazel lee las asignaciones del archivo platform_mappings en tu raíz del espacio de trabajo. También puedes establecer --platform_mappings=//:my_custom_mapping

Para obtener más detalles, consulta el diseño de asignaciones de plataformas.

Revisión de la API

Un platform es una colección de Destinos de constraint_value:

platform(
    name = "myplatform",
    constraint_values = [
        "@platforms//os:linux",
        "@platforms//cpu:arm",
    ],
)

Un constraint_value es una máquina propiedad. Valores del mismo “tipo” se agrupan en constraint_setting:

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. Es Los atributos declaran las herramientas de un idioma (como compiler = "//mytoolchain:custom_gcc"). Pase de proveedores esta información a las reglas que deben crearse con estas herramientas.

Las cadenas de herramientas declaran los constraint_value de las máquinas que pueden objetivo (target_compatible_with = ["@platforms//os:linux"]) y máquinas que sus herramientas pueden ejecutar exec_compatible_with = ["@platforms//os:mac"].

Cuando compilas $ bazel build //:myproject --platforms=//:myplatform, Bazel selecciona automáticamente una cadena de herramientas que puede ejecutarse en la máquina de compilación y objetos binarios de compilación para //:myplatform. Esto se conoce como resolución de la cadena de herramientas.

El conjunto de cadenas de herramientas disponibles se puede registrar en el archivo MODULE.bazel. con register_toolchains o al la línea de comandos con --extra_toolchains.

Obtén más información aquí.

Preguntas

Si necesita asistencia general o tiene preguntas sobre el cronograma de migración, comuníquese con bazel-debate o los propietarios de las reglas apropiadas.

Para debatir sobre el diseño y la evolución de las APIs de plataforma/cadena de herramientas, consulta lo siguiente: comunícate con bazel-dev.

Consulta también