linking against dylib built for MacOSX file '/usr/lib/libSystem.B.dylib' for architecture i386 - xcode

I recently switched my development MacBook from a classic MacBook (32 bit) to a MacBook Air (64 bit). I am trying to open a project that was made on my old MacBook (32 bit) running XCode 4.
The project is a PhoneGap application made in PhoneGap 1.7.0.
My new MacBook Air (64 bit) is running XCode 5.
I imported my developer profiles from my old MacBook to my new MacBook Air. But when I try to run it, I get the following error message.
I have tried changing the my architecture in the build settings to armv7 but still no luck :(
Does anyone know why I'm getting this error and how to fix it?
Thanks

OK so as it turns out, XCode 5 changes the default architecture to armv7 when my application does not support armv7. I am running Cordova 1.7.0 and that version does not have support for armv7 architecture.
Fix architecture issue:
Removed ALL architectures from Build Settings -->
Valid Architecture
Added armv6 to Build Settings --> Valid Architecture
Fix libSystem.B.dylib issue:
Removed /usr/lib/libSystem.B.dylib from Build Settings --> Linking --> Other Linker Flags
Also removed -weak_library from Build Settings --> Linking --> Other Linker Flags

Xcode 5 asks you to build your libraries for the simulator (1) and for iOS (2). You can then merge (3) these into a fat binary which you then link to your main project. I use the same flags as Xcode is using to build your main project (as seen in your screendump).
Expressed in common gnu toolchain variables I do:
1. Building a library for the simulator
CC=clang
IPHONEOS_DEPLOYMENT_TARGET=7.0
PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:$PATH"
CFLAGS="-arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.0.sdk -mios-simulator-version-min=7.0"
2. Building a library for iOS
CC=clang
IPHONEOS_DEPLOYMENT_TARGET=7.0
PATH="/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin:/Applications/Xcode.app/Contents/Developer/usr/bin:$PATH"
CFLAGS="-arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk -miphoneos-version-min=7.0"
3. Merging to a fat binary
Choose either of .a or .dylib depending on what you use:
lipo -create "your armv7 lib".a "your simulator lib".a -output "your lib".a
lipo -create "your armv7 lib".dylib "your simulator lib".dylib -output "your lib".dylib

Related

Can Xcode on m1 Mac build targeting Intel

I have a 2020 m1 MacBook Pro and need to build a .dylib library targeting x86_64 architecture in order to open it in a java project that is giving me the following error:
mach-o file, but is an incompatible architecture (have 'arm64', need 'x86_64')
I've checked this apple link where it says that Xcode on m1 automatically builds a universal executable https://developer.apple.com/documentation/apple-silicon/building-a-universal-macos-binary.
When I open my Build Settings to select the target Architecture I don't have other choices:
screenshot
How can I build the way I need to?

Build FFTW for Apple M1 and the older intel devices

I built FFTW on my Apple m1 computer. When I run lipo -info libfftw3.a (which is located in .libs/libfftw3.a). It says it is of architecture ARM64.
In my Xcode I set the build target to 10.11, for backward compatibility.
Now when I add the FFTW library into my Xcode project, it complains:
The linked library 'libfftw3.a' is missing one or more architectures
required by this target: x86_64.
How can I solve this? Do I need to build the library in an Intel device and create a universal library with these two libraries together (using lipo) or what's the right way to solve this?
You can configure it also with this line and it will build x86_64 & arm64 binary.
./configure CFLAGS="-arch arm64 -arch x86_64 -mmacosx-version-min=11.0"
In order to build a static library for both Intel and Apple silicon archictures, I need to build FFTW for both arch individually and then make an universal library. Here is how I do it.
Go to FFTW root folder
Build for Intel arch
./configure --prefix=/path/to/build/folder/lib-intel CFLAGS="-arch x86_64 -mmacosx-version-min=10.11”
make
make install
Build for arm64
./configure --prefix=/path/to/build/folder/lib-arm64 CFLAGS="-mmacosx-version-min=10.11”
make
make install
Make an universal build
lipo -create path/to/build/folder/lib-intel/libfftw3.a path/to/build/folder/lib-intel/libfftw3.a -output libfftw3_universal.a
Include libfftw3_universal.a in the Xcode project

CorePlot framework with universal build for Mac Apple Silicon

Is there a way to compile the CorePlot framework as a universal build including arm architectures ?
When I open the project on Xcode 12, I make sure I select Standard Architectures but it doesn't seem to be working. I've test it with the file command on terminal I only get 1 build for x86_64.
Is there a way to check what the $(ARCHS_STANDARD) variable value is ?
CorePlot framework:
https://github.com/core-plot/core-plot
Make sure you're using the code on the release-2.4 branch. Choose "Any Mac (Apple Silicon, Intel)" instead of "My Mac" from the Scheme menu at the top of the window before building the framework.
$ lipo -info (build folder)/CorePlot.framework/Versions/A/CorePlot
Architectures in the fat file: (build folder)/CorePlot.framework/Versions/A/CorePlot are:
x86_64 arm64

building for UIKitForMac, but linking in .tbd built for macOS

I'm trying to compile my iOS app to work on macOS and after checking the Mac checkbox, I'm getting this error on compile:
d: building for UIKitForMac, but linking in .tbd built for macOS, file '/Users/jan/Xcode-beta.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks//GLKit.framework/GLKit.tbd' for architecture x86_64
Any idea what it means and how to fix it?
Though I've not had this particular error I have had similar ones when trying to port from iPad to UIKitForMac. UIKitForMac appears to be the iOS SDK built for x86_64 when you're linking with frameworks. As a result it shouldn't be trying to pull the x86_64 files from the macOS SDK.
I'd be tempted to check over your 'architectures' and 'valid architectures' settings in Xcode to make sure that any settings you have are deleted and switched back to the standard ones.
Remove architectures

How to support both armv6 and armv7s for release build in xcode 4.5

I know that this is not possible and Apple planned it this way to force the users to upgrade their devices. But I just want to know if there is some workaround or hacks in able to do this? The client insists that we should still support armv6 because of a still "large" percentage of the app users.
I know a command called lipo to merge static libraries and I read somewhere that we can also use it to merge ipa files but I'm not sure how its exactly done. I did a couple of searching around already on google and this site, buts its hard to find a concrete answer.
I've been able to do this successfully with my app that's in the App Store. It supports armv6, armv7, and armv7s and iOS versions from 4.2 to 6.0. I've verified that it runs on older devices (iPhone 3G, iPod touch 2g) all the way through the iPhone 5.
This method requires having both Xcode 4.5 and an older version of Xcode installed simultaneously. I'm still on 4.3.2 for my older version, but 4.4 should work as well.
I had screenshots for this answer, but Stack Overflow won't let me post them because I'm new. :(
Setup in Xcode 4.5
Add a new build configuration for your armv6 build. I duplicated the Release config and named it Release_armv6.
Set the Architectures and Valid Architectures for your build configurations. For all but Release_armv6, use the default. For Release_armv6, manually set it to armv6.
http://i.stack.imgur.com/h8Mpl.png
If you're using iOS 6 features that Xcode 4.4 and below won't understand, you'll need to #ifdef these out for your armv6 build. In Build Settings under Other C Flags and Other C++ Flags I added -DARMV6_ONLY to my Release_armv6 config. Then wherever the code uses a new iOS 6 API, I do something like #ifndef ARMV6_ONLY / #endif as appropriate.
http://i.stack.imgur.com/czF6J.png
Add a new scheme and set it to use the Release_armv6 build configuration in all cases.
Under Build Phases, add a Run Script Build Phase with the following script (set the Shell to /bin/csh). This is where the magic happens. Edit the Configuration section: Determine your full path to the Release_armv6 build and substitute it for ARMV6_EXECUTABLE_PATH. Also set 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"
Build Process
When you're ready to create a release build, do it in the following order:
Close Xcode 4.5 and open Xcode 4.4 or below. Select your armv6 scheme and build it.
Close Xcode 4.4 or below and open Xcode 4.5. Select your Release scheme and build it.
That's pretty much it. Check the build output to verify that you got what you want - an executable with three architectures in it. The last output from the run script should tell you this.
If anyone has ideas to improve this, please feel free. I imagine you might be able to get fancy and call Xcode 4.4's "xcodebuild" command from within the build script, alleviating the need to switch between Xcode versions at all. But this works well enough for me. ;)
Caveats:
Just to be safe, you might want to edit your xib files in the older version of Xcode. So far it seems like 4.5 is backwards compatible, but you never know.
In fact, you might consider just doing most of your development, except for iOS 6-specific stuff, in the older Xcode. Depends on whatever's easiest for you.
There is a another way as gcc-4.2 still supports armv6, which won't require you to close Xcode 4.5 an open a previous version (for compilation, but not for running app on a 4.2 device) :
Add armv6 to both valid archs and archs :
Archs : $(ARCHS_STANDARD_32_BIT) armv6
Valid Architectures : armv6 armv7 armv7s
Vim (or TextEdit) your project.pbxproj file to replace IPHONEOS_DEPLOYMENT_TARGET to 4.0 - 4.1 - 4.2 as you need, Xcode 4.5 won't let you get below 4.3.
Then, if you build your project, you will see warnings :
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
Add a Build Rule for source files with names matching : *.[mc] that will use LLVM GCC 4.2
It works for static libraries, but not for apps :
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
For making it works for apps, we need to add the armv6 slice to this object file (which comes with the 5.1 SDK) :
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
Compile your project and check that your app contains all archs :
$ 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
Note that the dSYM file also contains all archs (useful for crash report symbolification) :
$ 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
I've sucessfully installed and launched the app on an iOS 4.2 2gen iPod touch by opening xcode 4.4.1, then Product -> Run without building.
When you Archive your product, you may experience again the Apple Mach-O Linker error, this time involving other files, such as libarclite_iphoneos.a or 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
The procedure used for crt1.3.1.o applies to these files too, and will fix the error allowing Xcode to successfully archive your project: you can use the path printed by ld to find the file and join the armv6 slice with lipo; just keep in mind that libclang_rt.ios.a in the previous versions of Xcode isn't located in Xcode.app/[...]/usr/lib/clang/4.1 but in Xcode.app/[...]/usr/lib/clang/4.0.
I've successfully archived the file, deployed it with an ad-hoc distribution profile, and tested on iPhone 3G (4.2.1) and iPhone 3GS (6.0).
Last issue : we can't launch app. In the Organizer, there is the message : Devices of type “iPhone 3G” are not supported by this version of Xcode.
But an ls in the DeviceSupport shows :
ls /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/
4.2 4.3 5.0 5.1 6.0 (10A403)
With no diffs in the 4.2 directory from Xcode 4.4.1.
The question is now : how Xcode detect is device is supported or not ?
Opening /Applications/Xcode.app/Contents/Developer//Platforms/iPhoneOS.platform/Developer//Library/PrivateFrameworks/DTDeviceKitBase.framework/DTDeviceKitBase with Hex Fiend (or another hex editor), and replacing ascii 4.3 with 4.2 make the error message disappear, and app installed on the device are listed (but device bullet in the device list is still red).
Then we need to edit /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks//DTDeviceKit.framework/Versions/Current/DTDeviceKit and replace :
Expired.deviceArchitecture.iPhone1,1.iPhone1,2.iPod1,1.iPod2,1.iPod2,2.armv6
to :
Expired.deviceArchitecture.iPhone0,1.iPhone0,2.iPod0,1.iPod0,1.iPod0,2.armv5
Then we have an orange bullet in the Organizer (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
The question is now : where Xcode Supported iOS Versions are defined ?
As there is a 4.2 directory in /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/, it should already be supported...
Tried to copy iPhoneOS4.2.sdk from Xcode 4.4.1 to /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/, but it don't make device supported.
So haven't found how to add 4.2 device support in Xcode 4.5. Any ideas ?
Conclusion : compiling for armv6/7/7s within Xcode 4.5 is possible. But it is not possible to start an app on a 4.2 armv6 device without starting Xcode 4.4.
Big update : it works with Xcode 4.5.2 !
Now the bullet is green in Xcode 4.5.2 :-)
The device appear in the drop down list near the Run button.
But when trying to run the app, got the message :
Xcode cannot run using the selected device.
Choose a destination with a supported architecture in order to run on this device.
Simply add armv6 to the valid architectures :-)
Other note : the Build Rule for source files with names matching : *.[mc] can use LLVM GCC 4.2 or Apple LLVM compiler 4.1, or Default compiler
Thanks for this useful script !
I successfully combined all infos from this entire post, the resulting complete script is below.
This script requires having both Xcode 4.5.x and a previous Xcode version supporting armv6 (Xcode 4.4.1 for instance, installed in /Applications/Xcode 4.4.1.app)
The script does NOT require to compile first in xcode 4.4.x, you just have to launch your latest Xcode, select the Release configuration and build. (the Release-armv6 configuration should have been defined like mentioned in the original post from Mike).
It will produce a .app compatible with armv6 armv7 and armv7s
Thanks to Mike for the original script !
#################
# 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"
Thanks for the post. We have a few apps to build so we automated the armv6 build using xcodebuild as you suggested. This is the part of our script (modified as we use bash) that does that, which can be added to your script above. This could be added before "# 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
Thank to Mike for this useful tutorial and script. As mentioned by Piotr in comments, the script is failing if you run the archive command from Xcode since it use another build directory for archiving.
Here below is my modification to the script to enable it for both normal release build and archive specific build.
It assumes that the armv6 build is run before as per original instructions from Mike. It use bash syntax because it is easier for me to strip-out the common base build directory. So this implies translation of the original script to bash which is only a matter of replacing setenv by export and changing the if statements syntax.
# 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"
I would like to share my experience with kenji's answer. I think it's the best one and the best way to build a universal app which runs on armv6 / armv7 / armv7s, from iOS3.1 to iOS7.
Just do exactly as kenji suggests.
You may ignore the parts about archiving the product, mainly if you send your app to apple via Application Loader (zipped).
Few more advices :
When you build for "distribution" configuration, xcode will validate the product, and you will get two warnings :
"architecture armv6 is not supported..."
"iOS deployment targets lower than 4.3 are not supported...".
Of course, because you actually build for armv6 and you set the deployment target to 3.1 or 4.2, for example !
So... just ignore these warnings.
After sending your app to itunes connect, you will receive a warning email from apple, saying that your app is not "Position Independent Executable".
Of course again, it's because your target is lower than 4.3.
Just ignore this warning.
At this date (2013 jul 03) I have successfully update an app to the appstore with this method, and it has passed validation. The app deployment target is iOS 3.1.2, and it supports armv6-armv7-armv7s.
I would like to say also that :
If you make a brand new app, just set the deployment target to iOS6 or iOS5. Ignore old OS.
If you have an old app sold since 2010, with dozens of thousands of users, you actually may have much more people who use it on armv6 than Apple usually says. I think 3 years is a too short period to drop support for these old devices, mainly if your app CAN run on them.
Apple has stopped accepting builds that support pre iOS5 devices and contain an iPhone 5 launch image. Here is the email for the last build I submitted that was build on Xcode 4.4.1
Dear developer,
We have discovered one or more issues with your recent delivery for "". To process your delivery, the following issues must be corrected:
Invalid Launch Image - Your app contains a launch image with a size modifier that is only supported for apps built with the iOS 6.0 SDK or later.
Once these issues have been corrected, go to the Version Details page and click "Ready to Upload Binary." Continue through the submission process until the app status is "Waiting for Upload." You can then deliver the corrected binary.
Regards,
The App Store team

Resources