xcode xcode4.5 armv7 armv6

Cómo admitir tanto armv6 como armv7s para la versión de lanzamiento en xcode 4.5



xcode4.5 (7)

¡Gracias por este útil script!

Combiné con éxito todas las informaciones de esta publicación completa, el guión completo resultante está a continuación. Este script requiere tener tanto Xcode 4.5.xy una versión previa de Xcode que soporta armv6 (Xcode 4.4.1 por ejemplo, instalado en / Applications / Xcode 4.4.1.app)

El script NO requiere compilar primero en xcode 4.4.x, solo tiene que iniciar su último Xcode, seleccione la configuración y compilación de la versión. (La configuración Release-armv6 debería haberse definido como se menciona en la publicación original de Mike).

Producirá un .app compatible con armv6 armv7 y armv7s

¡Gracias a Mike por el guion original!

################# # Configuration # ################# # Change this to the full path where Xcode 4.4 (or below) puts your armv6 output setenv ARMV6_OUTPUT_PATH "$BUILD_ROOT/Release-armv6-iphoneos/" setenv ARMV6_EXECUTABLE_PATH "$ARMV6_OUTPUT_PATH$EXECUTABLE_PATH" # Your "real" minimum OS version since Xcode 4.5 wants to make it iOS 4.3 # Must be 4.2 or below if you are supporting armv6... setenv MINIMUM_OS 4.2 ##################### # End configuration # ##################### # For debugging echo CURRENT_ARCH = $CURRENT_ARCH echo CONFIGURATION = $CONFIGURATION # Don''t need to do this for armv6 (built in older Xcode), simulator (i386), or debug build #if ("$CURRENT_ARCH" == "armv6") exit 0 if ("$CURRENT_ARCH" == "i386") exit 0 if ("$CONFIGURATION" != "Release" && "$CONFIGURATION" != "Beta Test") exit 0 # Paths setenv LIPO_PATH "$CODESIGNING_FOLDER_PATH/${EXECUTABLE_NAME}.lipo" setenv FINAL_PATH "$CODESIGNING_FOLDER_PATH/$EXECUTABLE_NAME" setenv FULL_INFO_PLIST_PATH "$CONFIGURATION_BUILD_DIR/$INFOPLIST_PATH" #log file for armv6 build echo "------------------------- BUILDING ARMV6 NOW -------------------------" setenv LOGFILE "$BUILD_ROOT/buildarmv6.txt" setenv CONFIGURATION_ARMV6 "${CONFIGURATION}-armv6" #build armv6 version echo "Building $FULL_PRODUCT_NAME armv6 CONFIG=$CONFIGURATION-armv6 target=$TARGETNAME" "/Applications/Xcode 4.4.1.app/Contents/Developer/usr/bin/xcodebuild" -project "${PROJECT_FILE_PATH}" -target "${TARGETNAME}" -sdk "${PLATFORM_NAME}" -configuration "$CONFIGURATION-armv6" CONFIGURATION_BUILD_DIR="$ARMV6_OUTPUT_PATH" >> "$LOGFILE" echo "---------------------------- ARMV6 BUILT -------------------------" # to check for armv6 build errors open "$LOGFILE" # Debug / sanity check lipo -info "$FINAL_PATH" ls -l "$ARMV6_EXECUTABLE_PATH" # Make sure something exists at $LIPO_PATH even if the next command fails cp -pv "$FINAL_PATH" "$LIPO_PATH" # If rebuilding without cleaning first, old armv6 might already be there so remove it # If not, lipo won''t output anything (thus the cp command just above) lipo -remove armv6 -output "$LIPO_PATH" "$FINAL_PATH" # Add armv6 to the fat binary, show that it worked for debugging, then remove temp file lipo -create -output "$FINAL_PATH" "$ARMV6_EXECUTABLE_PATH" "$LIPO_PATH" echo "------------------------- CHECK ARMV6 ARMV7 ARMV7S ARE MENTIONED BELOW -------------------------" lipo -info "$FINAL_PATH" echo "------------------------------------------------------------------------------------------------" rm -f "$LIPO_PATH" # Change Info.plist to set minimum OS version to 4.2 (instead of 4.3 which Xcode 4.5 wants) /usr/libexec/PlistBuddy -c "Set :MinimumOSVersion $MINIMUM_OS" "$FULL_INFO_PLIST_PATH" plutil -convert binary1 "$FULL_INFO_PLIST_PATH"

Sé que esto no es posible y Apple lo planeó de esta manera para obligar a los usuarios a actualizar sus dispositivos. Pero solo quiero saber si hay alguna solución o hacks capaz de hacer esto. El cliente insiste en que todavía debemos apoyar a armv6 debido a un porcentaje aún "grande" de los usuarios de la aplicación.

Conozco un comando llamado lipo para combinar bibliotecas estáticas y leo en alguna parte que también podemos usarlo para combinar archivos ipa pero no estoy seguro de cómo se hace exactamente. Hice un par de búsquedas en Google y en este sitio, pero es difícil encontrar una respuesta concreta.


Apple dejó de aceptar compilaciones que admitan dispositivos anteriores a iOS5 y contienen una imagen de lanzamiento de iPhone 5. Aquí está el correo electrónico de la última compilación que envié y que fue compilada en Xcode 4.4.1

Estimado desarrollador,

Hemos descubierto uno o más problemas con su entrega reciente para "". Para procesar su entrega, los siguientes problemas deben ser corregidos:

Imagen de inicio no válida: su aplicación contiene una imagen de inicio con un modificador de tamaño que solo se admite para las aplicaciones creadas con iOS 6.0 SDK o posterior.

Una vez que se hayan corregido estos problemas, vaya a la página de Detalles de la versión y haga clic en "Listo para cargar archivos binarios". Continúe con el proceso de envío hasta que el estado de la aplicación sea "Esperando carga". A continuación, puede entregar el binario corregido.

Saludos,

El equipo de App Store


Gracias a Mike por este útil tutorial y guión. Como menciona Piotr en los comentarios, la secuencia de comandos está fallando si ejecuta el comando de archivo desde Xcode ya que usa otro directorio de compilación para archivar.

A continuación, mi modificación al script para habilitarlo tanto para la compilación de lanzamiento normal como para la compilación específica del archivo.

Asume que la compilación de armv6 se ejecuta antes según las instrucciones originales de Mike. Utiliza la sintaxis de bash porque me resulta más fácil desmantelar el directorio de compilación base común. Entonces, esto implica la traducción del guión original a bash, que es solo cuestión de reemplazar setenv por exportación y cambiar la sintaxis de las sentencias if.

# Find the common base directory for both build XCODE_BUILD=${BUILD_ROOT%%/Build*} # Change this to the full path where Xcode 4.4 (or below) puts your armv6 output, using the previously derived base export ARMV6_EXECUTABLE_PATH="$XCODE_BUILD/Build/Products/Release_armv6-iphoneos/$EXECUTABLE_PATH"


Gracias por la publicacion. Tenemos algunas aplicaciones para compilar, así que automatizamos la compilación de armv6 usando xcodebuild como sugirió. Esta es la parte de nuestro script (modificado como usamos bash) que hace eso, que se puede agregar a su script anterior. Esto podría agregarse antes de "# Debug / sanity check"

setenv LOGFILE "/Users/xyz/Desktop/buildarmv6.txt" setenv CONFIGURATION_ARMV6 "${CONFIGURATION}_armv6" echo "Building $FULL_PRODUCT_NAME armv6 CONFIG=$CONFIGURATION_ARMV6 target=$TARGETNAME" "/Applications/Xcode 4.4.1.app/Contents/Developer/usr/bin/xcodebuild" -project "${PROJECT_FILE_PATH}" -target "${TARGETNAME}" -sdk "${PLATFORM_NAME}" -configuration "$CONFIGURATION_ARMV6" >> "$LOGFILE" echo "Built armv6" open "$LOGFILE" # to check for armv6 build errors


Hay otra forma en que gcc-4.2 aún soporta armv6, que no requerirá cerrar Xcode 4.5 y abrir una versión anterior (para compilación, pero no para ejecutar la aplicación en un dispositivo 4.2):

  • Agregue armv6 a ambos archios y arcos válidos:

Archs: $ (ARCHS_STANDARD_32_BIT) armv6

Arquitecturas válidas: armv6 armv7 armv7s

  • Vim (o TextEdit) su archivo project.pbxproj para reemplazar IPHONEOS_DEPLOYMENT_TARGET a 4.0 - 4.1 - 4.2 según lo necesite, Xcode 4.5 no le permitirá obtener 4.3 por debajo.

Entonces, si construyes tu proyecto, verás advertencias:

warning: no rule to process file ''$(PROJECT_DIR)/App/AppDelegate.m'' of type sourcecode.c.objc for architecture armv6 warning: no rule to process file ''$(PROJECT_DIR)/App/SomeFile.c'' of type sourcecode.c.c for architecture armv6

  • Agregue una Build Rule para los archivos fuente con nombres coincidentes: *.[mc] que usará LLVM GCC 4.2

Funciona para bibliotecas estáticas, pero no para aplicaciones:

ld: file is universal (4 slices) but does not contain a(n) armv6 slice: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o for architecture armv6

  • Para hacer que funcione para las aplicaciones, necesitamos agregar la división armv6 a este archivo de objeto (que viene con el SDK 5.1):

lipo /path/to-4.4/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk/usr/lib/crt1.3.1.o -extract armv6 -output /tmp/crt1.3.1-armv6.o lipo /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o /tmp/crt1.3.1-armv6.o -create -output /tmp/crt1.3.1-armv677s.o mv /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o.bkp mv /tmp/crt1.3.1-armv677s.o /Applications/Xcode.app/Contents//Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk/usr/lib/crt1.3.1.o

Compila tu proyecto y verifica que tu aplicación contenga todos los arch:

$ file DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp: Mach-O universal binary with 3 architectures DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp (for architecture armv6): Mach-O executable arm DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp (for architecture armv7): Mach-O executable arm DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app/TestApp (for architecture cputype (12) cpusubtype (11)): Mach-O executable arm

Tenga en cuenta que el archivo dSYM también contiene todos los archivos (útiles para la simbolización del informe de bloqueo):

$ file DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp: Mach-O universal binary with 3 architectures DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp (for architecture armv6): Mach-O dSYM companion file arm DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp (for architecture armv7): Mach-O dSYM companion file arm DerivedData/TestApp/Build/Products/Debug-iphoneos/TestApp.app.dSYM/Contents/Resources/DWARF/TestApp (for architecture cputype (12) cpusubtype (11)): Mach-O dSYM companion file arm

Instalé y lancé la aplicación con éxito en un iPod touch 2,2 de iOS 4.2 abriendo xcode 4.4.1, luego Product -> Run without building .

  • Cuando archivas tu producto, puedes experimentar nuevamente el error Apple Mach-O Linker, esta vez involucrando otros archivos, como libarclite_iphoneos.a o libclang_rt.ios.a :

ld: file is universal (2 slices) but does not contain a(n) armv6 slice: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_iphoneos.a for architecture armv6

ld: file is universal (2 slices) but does not contain a(n) armv6 slice: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/4.1/libclang_rt.ios.a for architecture armv6

El procedimiento utilizado para crt1.3.1.o también se aplica a estos archivos, y corregirá el error que permite a Xcode archivar exitosamente su proyecto: puede usar la ruta impresa por ld para encontrar el archivo y unirse a la división armv6 con lipo ; Solo tenga en cuenta que libclang_rt.ios.a en las versiones anteriores de Xcode no se encuentra en Xcode.app/[...]/usr/lib/clang/4.1 sino en Xcode.app/[...]/usr/lib/clang/4.0 .

Logré archivar exitosamente el archivo, lo implementé con un perfil de distribución ad-hoc y probé en iPhone 3G (4.2.1) e iPhone 3GS (6.0).

  • Último problema: no podemos iniciar la aplicación. En el Organizer , aparece el mensaje: Dispositivos de tipo "iPhone 3G" no son compatibles con esta versión de Xcode.

Pero un ls en DeviceSupport muestra:

ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/ 4.2 4.3 5.0 5.1 6.0 (10A403)

Sin diferencias en el directorio 4.2 de Xcode 4.4.1.

La pregunta ahora es: ¿cómo detecta Xcode el dispositivo es compatible o no?

Abrir /Applications/Xcode.app/Contents/Developer//Platforms/iPhoneOS.platform/Developer//Library/PrivateFrameworks/DTDeviceKitBase.framework/DTDeviceKitBase con Hex Fiend (u otro editor hexadecimal) y reemplazar ascii 4.3 con 4.2 cometer el error el mensaje desaparecerá y la aplicación instalada en el dispositivo aparecerá en la lista (pero la viñeta del dispositivo en la lista de dispositivos aún está en rojo).

Entonces tenemos que editar /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks//DTDeviceKit.framework/Versions/Current/DTDeviceKit y reemplazar:

Expired.deviceArchitecture.iPhone1,1.iPhone1,2.iPod1,1.iPod2,1.iPod2,2.armv6

a :

Expired.deviceArchitecture.iPhone0,1.iPhone0,2.iPod0,1.iPod0,1.iPod0,2.armv5

Luego tenemos una bala naranja en el Organizador (Xcode 4.5.1):

The version of iOS on “iPhone” is too old for use with this version of the iOS SDK. Please restore the device to a version of the OS listed below. OS Installed on iPhone 4.2.1 (8C148) Xcode Supported iOS Versions 6.0 (10A403) 5.1 5.0 4.3

La pregunta ahora es: ¿dónde se definen las versiones de iOS compatibles con Xcode?

Como hay un directorio 4.2 en /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/ , ya debería ser compatible ...

iPhoneOS4.2.sdk copiar iPhoneOS4.2.sdk desde Xcode 4.4.1 a /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/ , pero no hace que el dispositivo sea compatible.

Por lo tanto, no he encontrado la forma de agregar compatibilidad con 4.2 dispositivos en Xcode 4.5. Algunas ideas ?

Conclusión: compilar para armv6 / 7 / 7s dentro de Xcode 4.5 es posible. Pero no es posible iniciar una aplicación en un dispositivo 4.2 armv6 sin iniciar Xcode 4.4.

Gran actualización: ¡funciona con Xcode 4.5.2!

Ahora la viñeta está verde en Xcode 4.5.2 :-) El dispositivo aparece en la lista desplegable cerca del botón Ejecutar. Pero al intentar ejecutar la aplicación, recibí el mensaje:

Xcode cannot run using the selected device. Choose a destination with a supported architecture in order to run on this device.

Simplemente agrega armv6 a las arquitecturas válidas :-)

Otra nota: la Build Rule para los archivos fuente con nombres que coinciden: *.[mc] puede usar LLVM GCC 4.2 o Apple LLVM compiler 4.1 , o Default compiler


Me gustaría compartir mi experiencia con la respuesta de Kenji. Creo que es la mejor y la mejor forma de crear una aplicación universal que se ejecute en armv6 / armv7 / armv7s, desde iOS3.1 a iOS7.

Simplemente haz exactamente lo que sugiere kenji. Puede ignorar las partes sobre el archivo del producto, principalmente si envía su aplicación a Apple a través de Application Loader (comprimido).

Pocos consejos más:

Cuando construya para la configuración de "distribución", xcode validará el producto y obtendrá dos advertencias:

  • "la arquitectura armv6 no es compatible ..."
  • "Los objetivos de implementación de iOS inferiores a 4.3 no son compatibles ...".

Por supuesto, ¡porque realmente compila para armv6 y establece el destino de despliegue en 3.1 o 4.2, por ejemplo!

Entonces ... solo ignora estas advertencias.

Después de enviar su aplicación a itunes connect, recibirá un correo electrónico de advertencia de Apple, indicando que su aplicación no es "Ejecutable independiente de posición". Por supuesto, una vez más, es porque tu objetivo es inferior a 4.3. Solo ignora esta advertencia.

En esta fecha (2013 jul 03) he actualizado con éxito una aplicación a la tienda de aplicaciones con este método, y ha pasado la validación. El objetivo de implementación de la aplicación es iOS 3.1.2, y es compatible con armv6-armv7-armv7s.

Me gustaría decir también que:

  • Si crea una aplicación nueva, simplemente configure el destino de implementación en iOS6 o iOS5. Ignora el viejo sistema operativo.
  • Si tiene una aplicación antigua que se vendió desde 2010, con decenas de miles de usuarios, es posible que haya muchas más personas que la usen en Armv6 de lo que Apple suele decir. Creo que 3 años es un período demasiado corto para dejar de admitir estos dispositivos antiguos, principalmente si su aplicación PUEDE ejecutarse en ellos.

Pude hacerlo con éxito con mi aplicación que está en la App Store. Admite las versiones de armv6, armv7, y armv7s y iOS de 4.2 a 6.0. Comprobé que se ejecuta en dispositivos más antiguos (iPhone 3G, iPod touch 2g) hasta el iPhone 5.

Este método requiere tener simultáneamente Xcode 4.5 y una versión anterior de Xcode. Todavía estoy en 4.3.2 para mi versión anterior, pero 4.4 debería funcionar también.

Tenía capturas de pantalla para esta respuesta, pero no me deja publicarlas porque soy nuevo. :(

Configuración en Xcode 4.5

  1. Agregue una nueva configuración de compilación para su compilación de armv6. Dupliqué la configuración de liberación y la llamé Release_armv6.

  2. Establezca las Arquitecturas y las Arquitecturas válidas para sus configuraciones de compilación. Para todos menos Release_armv6, use el predeterminado. Para Release_armv6, configúrelo manualmente en armv6 . http://i.stack.imgur.com/h8Mpl.png

  3. Si está utilizando las características de iOS 6 que Xcode 4.4 y siguientes no comprenderán, necesitará #ifdef estos para su compilación de armv6. En Configuración de compilación en Otros indicadores C y otras marcas de C ++ agregué -DARMV6_ONLY a mi configuración de Release_armv6. Entonces, donde sea que el código use una nueva API de iOS 6, hago algo como #ifndef ARMV6_ONLY / #endif según corresponda. http://i.stack.imgur.com/czF6J.png

  4. Agregue un nuevo esquema y configúrelo para utilizar la configuración de compilación Release_armv6 en todos los casos.

  5. En Fases de compilación, agregue una Fase de compilación Ejecutar script con la siguiente secuencia de comandos (establezca el Shell en / bin / csh ). Aquí es donde sucede la magia. Edite la sección Configuración: determine su ruta completa a la compilación Release_armv6 y sustitúyala por ARMV6_EXECUTABLE_PATH. También configure MINIMUM_OS.

# # Script to add armv6 architecture to iOS executable built with Xcode 4.5 # ################# # Configuration # ################# # Change this to the full path where Xcode 4.4 (or below) puts your armv6 output setenv ARMV6_EXECUTABLE_PATH "$BUILD_ROOT/Release_armv6-iphoneos/$EXECUTABLE_PATH" # Your "real" minimum OS version since Xcode 4.5 wants to make it iOS 4.3 # Must be 4.2 or below if you are supporting armv6... setenv MINIMUM_OS 4.2 ##################### # End configuration # ##################### # For debugging echo CURRENT_ARCH = $CURRENT_ARCH echo CONFIGURATION = $CONFIGURATION # Don''t need to do this for armv6 (built in older Xcode), simulator (i386), or debug build if ("$CURRENT_ARCH" == "armv6") exit 0 if ("$CURRENT_ARCH" == "i386") exit 0 if ("$CONFIGURATION" != "Release" && "$CONFIGURATION" != "Beta Test") exit 0 # Paths setenv LIPO_PATH "$CODESIGNING_FOLDER_PATH/${EXECUTABLE_NAME}.lipo" setenv FINAL_PATH "$CODESIGNING_FOLDER_PATH/$EXECUTABLE_NAME" setenv FULL_INFO_PLIST_PATH "$CONFIGURATION_BUILD_DIR/$INFOPLIST_PATH" # Debug / sanity check lipo -info "$FINAL_PATH" ls -l "$ARMV6_EXECUTABLE_PATH" # Make sure something exists at $LIPO_PATH even if the next command fails cp -pv "$FINAL_PATH" "$LIPO_PATH" # If rebuilding without cleaning first, old armv6 might already be there so remove it # If not, lipo won''t output anything (thus the cp command just above) lipo -remove armv6 -output "$LIPO_PATH" "$FINAL_PATH" # Add armv6 to the fat binary, show that it worked for debugging, then remove temp file lipo -create -output "$FINAL_PATH" "$ARMV6_EXECUTABLE_PATH" "$LIPO_PATH" lipo -info "$FINAL_PATH" rm -f "$LIPO_PATH" # Change Info.plist to set minimum OS version to 4.2 (instead of 4.3 which Xcode 4.5 wants) /usr/libexec/PlistBuddy -c "Set :MinimumOSVersion $MINIMUM_OS" "$FULL_INFO_PLIST_PATH" plutil -convert binary1 "$FULL_INFO_PLIST_PATH"

Proceso de compilación

Cuando esté listo para crear una versión de lanzamiento, hágalo en el siguiente orden:

  1. Cierre Xcode 4.5 y abra Xcode 4.4 o inferior. Seleccione su esquema de armv6 y compárelo.

  2. Cierre Xcode 4.4 o más abajo y abra Xcode 4.5. Seleccione su esquema de lanzamiento y compárelo.

Eso es practicamente todo. Compruebe la salida de compilación para verificar que obtuvo lo que desea, un ejecutable con tres arquitecturas. El último resultado del script de ejecución debería decirle esto.

Si alguien tiene ideas para mejorar esto, siéntase libre. Me imagino que podrías ser elegante y llamar al comando "xcodebuild" de Xcode 4.4 desde el script de construcción, aliviando la necesidad de cambiar entre las versiones de Xcode. Pero esto funciona lo suficientemente bien para mí. ;)

Advertencias:

  • Solo para estar seguro, es posible que desee editar sus archivos xib en la versión anterior de Xcode. Hasta ahora, parece que 4.5 es compatible con versiones anteriores, pero nunca se sabe.

  • De hecho, puede considerar hacer la mayor parte de su desarrollo, excepto para cosas específicas de iOS 6, en el antiguo Xcode. Depende de lo que sea más fácil para ti.