Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a armv7 arm64 fat binary that will run on iOS 5 through 7?

Tags:

xcode

ios

iphone

Apple has changed instruction sets over the years. Since a single programs may need to run on more than one kind of machine, Apple uses 'fat binaries' constructed by a tool named 'lipo'. You tell Xcode to compile your program multiple times, once for each machine type, and lipo binds them together.

Apple recently came out with its fourth instruction set for iOS. The first phones used Armv6, from the 3GS, we had Armv7, a few new instructions were added for Armv7s, and now, the 5S adds Arm64.

I like my programs to run under a range of operating systems, so I set my MIN_DEPLOYMENT_TARGET to 5.0, so Apple will load the program on machines from 5.0 on. But when try that in the current version of Xcode, I get an error message saying that isn't possible in Arm64.

OK, I set a conditional build settings: the MIN_DEPLOYMENT_TARGET is 5.0 for architectures other than Arm64, but it's set to 7.0 for Arm64. Now the program compiles, links, and lipos. But now, since one of the compilations is iOS 7.0 only, I get a bunch of warnings that my program contains calls for older operating systems. I know that. It's intentional - so the program will run on those older systems. On an iOS 7 system, those old routines aren't called, instead, at runtime, the program calls their modern replacements. I can get the compiler to stop complaining with:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
// old code here.
#pragma clang diagnostic pop

and the program works fine on iOS 7 devices, both Armv7 and Arm64. A bit of diagnostic code verifies that when run on an Arm64 device, the Arm64 fork is actually being used.

Running lipo on the binary reports that it has the expected architectures in it.

But, and it's a big one: when I try to install the app on an iOS 5 device, Xcode just puts up an alert: "There was an internal API error."

I think there's a bug in iOS 5 and iOS 6, such that they don't ignore the forks that are from the future. The loader should simply ignore the forks it doesn't recognize. But that's not the way it works.

Apple is never going to fix iOS 5. I thought Apple might work around the problem when the app is loaded onto a device: have Xcode strip the unneeded fork, and re-sign the (now modified) binary. Similarly, downloading from iTunes could strip the unneeded fork and re-sign. But Apple is unlikely to do this: Apple wants everyone who can to upgrade to iOS7. Apple solution for those who can't upgrade is: buy new hardware.

So, we're stuck. You can have a single title in the app store that supports 5&6, and issue an update that's for 7 that's fat armv7 and arm64, so your users who have iOS7 will get the fat one, and your users who have 5 or 6 will get the old one, but you can only do it once. Once you post the 7 update, you can never update the 5&6 update ever again.

Is there a way around this? I want a single program that runs on Armv7 and Arm64, and iOS 5&6 for the armv7 side, iOS 7 for armv7 on harder that isn't arm64 and iOS 7 arm64 where its supported, How?

like image 263
DavidPhillipOster Avatar asked Jan 12 '23 02:01

DavidPhillipOster


2 Answers

Binaries with 64-bit slivers cannot be opened on iOS 5. It is an OS-level limitation, and there is no way around it. Generally, it should not be necessary to support iOS 5 any more, but I'm sure someone somewhere has a legitimate reason to support it, and hopefully they'll find this question.

If you must support iOS 5, you have to remove the sliver for 64-bit. I This does not prevent your app from working on 64-bit systems. It just makes it run as a 32-bit app. Most users won't even notice the difference.

like image 98
Holly Avatar answered Jan 21 '23 04:01

Holly


As of this current Xcode version (Version 5.0 (5A1412)):

Note: A future version of Xcode will let you create a single app that supports the 32-bit runtime on iOS 6 and later, and that supports the 64-bit runtime on iOS 7. Apple Source

like image 29
David Wong Avatar answered Jan 21 '23 02:01

David Wong