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