如何制作一个armv7 arm64胖二进制文件,可以在iOS 5到7上运行?

苹果多年来改变了指令集。 由于单个程序可能需要在多种机器上运行,所以苹果使用由“lipo”工具构build的“fat binaries”。 你告诉Xcode多次编译你的程序,每种机器types一次,lipo将它们绑定在一起。

苹果最近推出了iOS的第四套指令。 第一部手机使用Armv6,从3GS开始,我们有了Armv7,为Armv7增加了一些新的说明,现在,5S增加了Arm64。

我喜欢我的程序在一系列操作系统下运行,所以我将MIN_DEPLOYMENT_TARGET设置为5.0,所以苹果会从5.0开始将程序加载到机器上。 但是,当在当前版本的Xcode中尝试时,我收到一条错误消息,说在Arm64中是不可能的。

好的,我设置了一个条件构build设置:对于Arm64以外的架构,MIN_DEPLOYMENT_TARGET是5.0,但对于Arm64,它被设置为7.0。 现在程序编译,链接和lipos。 但现在,由于其中一个编译只有iOS 7.0,所以我收到了一些警告,说我的程序包含对较老的操作系统的调用。 我知道。 这是故意的 – 所以程序将运行在那些较旧的系统上。 在iOS 7系统中,这些旧例程不会被调用,而是在运行时调用它们的现代替代品。 我可以让编译器停止抱怨:

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

该程序在iOS 7设备上运行良好,Armv7和Arm64。 一些诊断代码validation在Arm64设备上运行时,实际上正在使用Arm64分叉。

在二进制文件上运行lipo报告,它具有预期的体系结构。

但是,这是一个很大的问题:当我尝试在iOS 5设备上安装应用程序时,Xcode只是提醒一下:“有一个内部的API错误。

我认为在iOS 5和iOS 6中存在一个错误,这样他们就不会忽略来自未来的叉子。 加载器应该忽略它不认识的叉子。 但这不是它的工作方式。

苹果是永远不会修复iOS 5.我认为苹果可能会解决这个问题,当应用程序被加载到设备上:有Xcode剥离不需要的分叉,并重新签署(现在修改)的二进制文件。 同样,从iTunes下载可以去掉不需要的分支并重新签名。 但苹果不太可能这样做:苹果希望每个人都可以升级到iOS7。 对于那些无法升级的苹果解决scheme是:购买新的硬件。

所以我们被卡住了 你可以在支持5&6的app store中拥有一个标题,并且发布一个更新,这个更新是7个胖胖的armv7和arm64,所以拥有iOS7的用户将获得胖胖的用户,而拥有5或6的用户将得到老的,但是你只能做一次。 一旦你发布了7更新,你永远不会再次更新5&6更新。

有没有解决的办法? 我想要一个在Armv7和Arm64上运行的程序,在armv7上运行iOS 5&6,在armv7上运行iOS 7,而不是在arm64和iOS 7 arm64上运行。

具有64位条形码的二进制文件无法在iOS 5上打开。这是操作系统级限制,无法解决。 一般来说,不需要再支持iOS 5,但是我确定某个地方有人有合理的理由支持它,希望他们能find这个问题。

如果您必须支持iOS 5,则必须删除64位的条子。 我这并不妨碍你的应用程序在64位系统上工作。 它只是使它作为一个32位应用程序运行。 大多数用户甚至不会注意到这种差异。

从目前的Xcode版本(版本5.0(5A1412))开始:

注意:未来版本的Xcode将允许您创build一个支持iOS 6及更高版本的32位运行时的应用程序,并支持iOS 7上的64位运行时。Apple Source

苹果公司在iOS 5.1中解决了这个问题,所以如果你将你的min-deployment-target设置为5.1,那么你可以制作一个32位的二进制文件,它将在5.1版本中工作。 我在5.1出来之前写下了原来的问题。