Inicio > Apple, Desarrollo, Tutorial > XCode 4.2 vs. iPhone 3G: todavía se puede

XCode 4.2 vs. iPhone 3G: todavía se puede

Esperaba que el menguado soporte a los procesadores ARMv6 volviese en la versión definitiva de XCode 4.2, pero no fue así: Apple aparentemente sólo soporta ahora los procesadores a partir del iPhone 3GS. Afortunadamente, todavía se puede usar la última herramienta de Cupertino para desarrollar para nuestros iPhone 3G e iPod Touch de segunda generación.

SadIphoneDurante la beta de iOS 5 (y XCode 4.2) se ha notado que el soporte para los procesadores con el juego de instrucciones ARMv6 era cada vez menor. Si el iPhone original y los iPod Touch de primera generación ya se quedaron fuera al no ser actualizables a iOS 4, los siguientes en la lista eran el iPhone 3G y el iPod Touch de segunda generación. El reemplazo del compilador GCC por el nuevo LLVM 3.0 ha traído muchas ventajas a los desarrolladores, pero todos los esfuerzos de Apple se han centrado en los procesadores basados en el núcleo Cortex (con juego de instrucciones ARMv7) y han dejado de lado las plataformas anteriores. Quizá para los nuevos desarrollos orientados a iPhone 4 e iPad no sea mucho problema, al orientarse hacia iOS 5, pero si deseamos seguir soportando iOS 4 al completo toca buscar alternativas.

La primera y principal, es no dar el salto por el momento a XCode 4.2. Espero que hayáis guardado la instalación de versiones anteriores de XCode (muy recomendable como práctica habitual) y sigáis compilando vuestros proyectos con el SDK de iOS 4/4.2 con el compilador GCC. Es la forma más segura y fiable para obtener software que funciona a la perfección en ambas plataformas y obtener el mejor rendimiento de ambas.

El problema aparece al querer aprovechar funcionalidades nuevas aparecidas en iOS 5: toca emplear el nuevo SDK en XCode 4.2 y hacer código que determine el sistema operativo en tiempo de ejecución. No hay absolutamente ningún problema con eso, y está perfectamente documentado cómo hacerlo. Lo malo es que si comprobamos las opciones del proyecto veremos que sólo aparece una arquitectura disponible: ARMv7. Si se crea un nuevo proyecto y se intenta ejecutar sobre un iPhone 3G o iPod Touch de segunda generación, seremos castigados con el mensaje “application executable is missing a required architecture. At least one of the following architecture(s) must be present: armv6”.

Primer paso: vuelta al ‘fat binary

El primer paso a realizar en nuestro proyecto para volver a ser ejecutables en las plataformas más veteranas, es volver a agregar soporte a los procesadores basados en el juego de instrucciones ARMv6 y los ejecutables “fat binary”. Los ejecutables de este tipo se compilan varias veces, cada una de ellas para una arquitectura hardware distinta, y los ejecutables se empaquetan todos juntos. Al incorporar dos binarios completos, se pueden hacer optimizaciones específicas a cada plataforma e incluso emplear opciones de compilación diferentes.

Al seleccionar el proyecto en XCode podremos ver que en la nueva versión 4.2 sólo aparece una arquitectura: “Standard ARMv7”. Para agregar soporte a ARMv6 basta con hacer click sobre la línea de “Architectures” y seleccionar “Other…”:

Xcode-settings-1a

Pulsando el botón ‘+’ agregamos la arquitectura ‘armv6’. Finalmente, editamos la entrada “$(ARCHS_STANDARD_32_BIT)” y la reemplazamos por “armv7”:

Xcode-settings-1b

Haremos exactamente lo mismo en la sección “Valid Architectures”. Si seleccionamos los targets del proyecto los cambios deberían aparecer también, pero siempre está bien comprobarlo y realizar los cambios manualmente en caso de que no se propaguen de forma automática. El resultado final aparecerá así, tanto en la sección de Proyecto como de Targets:

Xcode-settings-1

La opción “Build Active Architecture Only” debe estar desactivada, para que XCode genere siempre el código para todas las arquitecturas, y no solamente para el target actual seleccionado.

Segundo paso: selección de compilador

Mientras que en las versiones antiguas de XCode se podía elegir entre GCC y LLVM, en la nueva versión de XCode disponemos de LLVM 3.0 (como opción predeterminada) y LLVM GCC 4.2 que tampoco ofrece muchas ventajas en nuestro caso. Así que optaremos por el compilador LLVM 3.0:

Xcode-settings-2

Tercer paso: deployment target

No nos olvidemos de recordar a XCode que queremos que tenga en cuenta los dispositivos con iOS 4 al depurar nuestras aplicaciones. En este ejemplo seleccionamos iOS 4.2, que es la última versión del sistema operativo que se puede ejecutar en el iPhone 3G, aunque se puede seleccionar iOS 4.0. (Si optamos por esta última opción, hay que añadir soporte de depuración por medio de la opción en Xcode > Preferences > Downloads).

Xcode-settings-3

También toca echarle un vistazo al archivo .plist del proyecto y, o bien quitar cualquier requerimiento del mismo hacia las plataformas ARMv7 eliminando totalmente los requerimientos de arquitectura, o agregar manualmente soporte para la dos: ARMv6 y ARMv7:

Xcode-settings-5

Cuarto paso: ajustar el optimizador de LLVM o donde empiezan los problemas

Aquí es donde más se nota que el compilador LLVM realmente no se preocupa por las plataformas más veteranas. Lo más probable es que, si paramos en este punto, nuestro programa funcione perfectamente en modo “Debug”, pero o bien no arranque dando extrañísimos errores o bien tenga un comportamiento de lo más errático en un iPhone 3G cuando compilemos en modo “Release”, aunque funcione perfectamente en un iPhone 4. Por qué? Para resumir: el optimizador del compilador LLVM está roto para las arquitecturas ARMv6 y el código que genera, simplemente, contiene errores.

Afortunadamente, XCode nos permite especificar ajustes independientes para cada arquitectura, así que podemos evitar el problema al generar el código para la arquitectura ARMv6. Para ello, tanto en las opciones de Proyecto como de Target, localizaremos las opciones de optimización. Normalmente, al expandir la sección, veremos opciones para “Debug” y “Release”, con las optimizaciones desactivadas y activadas respectivamente. Para desactivar el optimizador en la versión Release de la arquitectura ARMv6, pulsaremos sobre el botón “+” en la opción release, y agregaremos reglas independientes para ARMv6 y ARMv7: Sin optimizaciones (“None [-O0]”) para la primera y optimizado (“Fastest, Smallest [-Os]”) para la segunda:

Xcode-settings-4

Lamentablemente configurar así el proyecto hará que la versión ejecutable para el procesador más veterano (y menos potente) sea incluso más lenta, al no poder aprovechar las optimizaciones del compilador. Pero por lo menos, dispondremos de un programa que funcionará desde un iPhone 3G hasta un flamante iPhone 4S.

De todas formas y como consejo final: si lo que buscáis es dar soporte sólido a versiones antiguas de los dispositivos o sistemas operativos, mejor seguir utilizando versiones de XCode anteriores a la 4.2 (o XCode 3 para iOS 3), quizá instalados en dos carpetas diferentes y seleccionar el entorno de desarrollo dependiendo del hardware para el que estemos desarrollando. Aunque Apple quiera olvidarse de los iPhone ó iPod Touch más “clásicos”, sus usuarios se merecen este pequeño esfuerzo por nuestra parte.

Aunque lo que realmente deseo es que Apple no se olvide de nuestros dispositivos más veteranos y arregle el optimizador del compilador LLVM en próximas versiones de XCode.

Anuncios
Categorías:Apple, Desarrollo, Tutorial Etiquetas: , , , , , , , ,
  1. 17/Nov/2011 en 9:38 pm

    Excelente muy buena info gracias x el dato amigo muy bien explicado

  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: