Migra de Xcode a Bazel

Informar un problema Ver código fuente Nocturno · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

En esta página, se describe cómo compilar o probar un proyecto de Xcode con Bazel. Describe las diferencias entre Xcode y Bazel, y proporciona los pasos para convertir un proyecto de Xcode en un proyecto de Bazel. También proporciona soluciones para solucionar problemas y abordar errores comunes.

Diferencias entre Xcode y Bazel

  • Bazel requiere que especifiques de forma explícita cada destino de compilación y sus dependencias, además de la configuración de compilación correspondiente a través de reglas de compilación.

  • Bazel requiere que todos los archivos de los que depende el proyecto estén presentes en el directorio del espacio de trabajo o se especifiquen como importaciones en el archivo WORKSPACE.

  • Cuando compilas proyectos de Xcode con Bazel, los archivos BUILD se convierten en la fuente de verdad. Si trabajas en el proyecto en Xcode, debes generar una nueva versión del proyecto de Xcode que coincida con los archivos BUILD usando rules_xcodeproj cada vez que actualices los archivos BUILD. Algunos cambios en los archivos BUILD, como agregar dependencias a un destino, no requieren que se regenere el proyecto, lo que puede acelerar el desarrollo. Si no usas Xcode, los comandos bazel build y bazel test proporcionan capacidades de compilación y prueba con ciertas limitaciones que se describen más adelante en esta guía.

Antes de comenzar

Antes de comenzar, haz lo siguiente:

  1. Instala Bazel si aún no lo hiciste.

  2. Si no conoces Bazel ni sus conceptos, completa el instructivo de la app para iOS. Debes comprender el espacio de trabajo de Bazel, incluidos los archivos WORKSPACE y BUILD, así como los conceptos de destinos, reglas de compilación y paquetes de Bazel.

  3. Analizar y comprender las dependencias del proyecto

Analiza las dependencias del proyecto

A diferencia de Xcode, Bazel requiere que declares explícitamente todas las dependencias para cada destino en el archivo BUILD.

Para obtener más información sobre las dependencias externas, consulta Cómo trabajar con dependencias externas.

Compila o prueba un proyecto de Xcode con Bazel

Para compilar o probar un proyecto de Xcode con Bazel, haz lo siguiente:

  1. Crea el archivo WORKSPACE

  2. (Experimental) Integrate SwiftPM dependencies

  3. Crea un archivo BUILD:

    a. Agrega el destino de la aplicación

    b. (Opcional) Agrega los objetivos de prueba

    c. Agrega los destinos de la biblioteca

  4. (Opcional) Granulariza la compilación

  5. Ejecuta la compilación

  6. Genera el proyecto de Xcode con rules_xcodeproj

Paso 1: Crea el archivo WORKSPACE

Crea un archivo WORKSPACE en un directorio nuevo. Este directorio se convierte en la raíz del espacio de trabajo de Bazel. Si el proyecto no usa dependencias externas, este archivo puede estar vacío. Si el proyecto depende de archivos o paquetes que no se encuentran en uno de los directorios del proyecto, especifica estas dependencias externas en el archivo WORKSPACE.

Paso 2: (Experimental) Integra dependencias de SwiftPM

Para integrar dependencias de SwiftPM en el espacio de trabajo de Bazel con swift_bazel, debes convertirlas en paquetes de Bazel como se describe en el siguiente instructivo.

Paso 3: Crea un archivo BUILD

Una vez que hayas definido el espacio de trabajo y las dependencias externas, deberás crear un archivo BUILD que le indique a Bazel cómo se estructura el proyecto. Crea el archivo BUILD en la raíz del espacio de trabajo de Bazel y configúralo para que realice una compilación inicial del proyecto de la siguiente manera:

Nota: Para obtener más información sobre los paquetes y otros conceptos de Bazel, consulta Espacios de trabajo, paquetes y destinos.

Paso 3a: Agrega el destino de la aplicación

Agrega un objetivo de regla macos_application o ios_application. Este destino compila un paquete de aplicación para macOS o iOS, respectivamente. En el destino, especifica, como mínimo, lo siguiente:

  • bundle_id: Es el ID del paquete (ruta de DNS inversa seguida del nombre de la app) del archivo binario.

  • provisioning_profile: Perfil de aprovisionamiento de tu cuenta de desarrollador de Apple (si compilas para un dispositivo iOS).

  • families (solo para iOS): Indica si se debe compilar la aplicación para iPhone, iPad o ambos.

  • infoplists: Es la lista de archivos .plist que se combinarán en el archivo Info.plist final.

  • minimum_os_version: Es la versión mínima de macOS o iOS que admite la aplicación. Esto garantiza que Bazel compile la aplicación con los niveles de API correctos.

Paso 3b: Agrega los objetivos de la prueba (opcional)

Las reglas de compilación de Apple de Bazel admiten la ejecución de pruebas de unidades y de IU en todas las plataformas de Apple. Agrega destinos de prueba de la siguiente manera:

  • macos_unit_test para ejecutar pruebas de unidades basadas en bibliotecas y aplicaciones en macOS

  • ios_unit_test para compilar y ejecutar pruebas de unidades basadas en bibliotecas en iOS.

  • ios_ui_test para compilar y ejecutar pruebas de la interfaz de usuario en el simulador de iOS

  • Existen reglas de prueba similares para tvOS, watchOS y visionOS.

Como mínimo, especifica un valor para el atributo minimum_os_version. Si bien otros atributos de empaquetado, como bundle_identifier y infoplists, se establecen de forma predeterminada en los valores más utilizados, asegúrate de que esos valores predeterminados sean compatibles con el proyecto y ajústalos según sea necesario. Para las pruebas que requieren el simulador de iOS, también debes especificar el nombre del destino ios_application como el valor del atributo test_host.

Paso 3c: Agrega los destinos de la biblioteca

Agrega un destino objc_library para cada biblioteca de Objective-C y un destino swift_library para cada biblioteca de Swift de la que dependan la aplicación o las pruebas.

Agrega los destinos de la biblioteca de la siguiente manera:

  • Agrega los destinos de la biblioteca de la aplicación como dependencias de los destinos de la aplicación.

  • Agrega los destinos de la biblioteca de pruebas como dependencias a los destinos de prueba.

  • Enumera las fuentes de implementación en el atributo srcs.

  • Enumera los encabezados en el atributo hdrs.

Puedes explorar ejemplos existentes para varios tipos de aplicaciones directamente en el directorio de ejemplos de rules_apple. Por ejemplo:

Para obtener más información sobre las reglas de compilación, consulta Apple Rules for Bazel.

En este punto, es recomendable probar la compilación:

bazel build //:<application_target>

Paso 4: (Opcional) Desglosa la compilación

Si el proyecto es grande o a medida que crece, considera dividirlo en varios paquetes de Bazel. Este mayor nivel de detalle proporciona lo siguiente:

  • Mayor incrementalidad de las compilaciones

  • Mayor paralelización de las tareas de compilación

  • Mejor mantenimiento para futuros usuarios

  • Mejor control sobre la visibilidad del código fuente en los destinos y paquetes Esto evita problemas como que las bibliotecas que contienen detalles de implementación se filtren en las APIs públicas.

Sugerencias para granularizar el proyecto:

  • Coloca cada biblioteca en su propio paquete de Bazel. Comienza con los que requieren la menor cantidad de dependencias y avanza por el árbol de dependencias.

  • A medida que agregues archivos BUILD y especifiques destinos, agrega estos destinos nuevos a los atributos deps de los destinos que dependen de ellos.

  • La función glob() no cruza los límites de los paquetes, por lo que, a medida que aumenta la cantidad de paquetes, se reduce la cantidad de archivos que coinciden con glob().

  • Cuando agregues un archivo BUILD a un directorio main, también agrega un archivo BUILD al directorio test correspondiente.

  • Aplicar límites de visibilidad adecuados en todos los paquetes

  • Compila el proyecto después de cada cambio importante en los archivos BUILD y corrige los errores de compilación a medida que los encuentres.

Paso 5: Ejecuta la compilación

Ejecuta la compilación completamente migrada para asegurarte de que se complete sin errores ni advertencias. Ejecuta cada aplicación y destino de prueba de forma individual para encontrar más fácilmente las fuentes de los errores que se produzcan.

Por ejemplo:

bazel build //:my-target

Paso 6: Genera el proyecto de Xcode con rules_xcodeproj

Cuando se compila con Bazel, los archivos WORKSPACE y BUILD se convierten en la fuente de verdad sobre la compilación. Para que Xcode lo sepa, debes generar un proyecto de Xcode compatible con Bazel usando rules_xcodeproj.

Solución de problemas

Los errores de Bazel pueden surgir cuando se desincroniza con la versión de Xcode seleccionada, como cuando aplicas una actualización. Si tienes problemas con Xcode, por ejemplo, el error "Se debe especificar la versión de Xcode para usar un CROSSTOOL de Apple", puedes probar lo siguiente.

  • Ejecuta Xcode de forma manual y acepta los términos y condiciones.

  • Usa Xcode select para indicar la versión correcta, acepta la licencia y borra el estado de Bazel.

  sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  sudo xcodebuild -license
  bazel sync --configure
  • Si esto no funciona, también puedes intentar ejecutar bazel clean --expunge.