如何制作将在 iOS 5 到 7 上运行的 armv7 arm64 胖二进制文件



多年来,Apple一直在更改指令集。由于单个程序可能需要在多种机器上运行,因此Apple使用由名为"lipo"的工具构建的"胖二进制文件"。你告诉 Xcode 多次编译你的程序,每种机器类型编译一次,然后 lipo 将它们绑定在一起。

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

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

好的,我设置了一个条件构建设置:对于 Arm64 以外的体系结构,MIN_DEPLOYMENT_TARGET为 5.0,但对于 Arm64,设置为 7.0。现在程序编译,链接和脂。但是现在,由于其中一个编译版本仅是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。一些诊断代码验证在 Arm64 设备上运行时,是否实际使用了 Arm64 分支。

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

但是,这是一个很大的问题:当我尝试在iOS 5设备上安装该应用程序时,Xcode只是发出警报:"存在内部API错误。

我认为iOS 5和iOS 6中存在一个错误,因此它们不会忽略来自未来的分叉。加载器应该简单地忽略它无法识别的叉子。但这不是它的工作方式。

苹果永远不会修复iOS 5。我认为当应用程序加载到设备上时,Apple可能会解决此问题:让Xcode剥离不需要的分叉,然后重新签名(现已修改的)二进制文件。同样,从iTunes下载可能会剥离不需要的分叉并重新签名。但苹果不太可能这样做:苹果希望每个能够升级到iOS7的人。 对于那些无法升级的人来说,Apple的解决方案是:购买新硬件。

所以,我们被困住了。你可以在支持5&6的应用商店中有一个游戏,并发布一个针对7的更新,即fat 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,但我相信某个地方有人有合法的理由支持它,希望他们会找到这个问题。

如果必须支持iOS 5,则必须删除64位的条子。I 这不会阻止您的应用程序在 64 位系统上运行。它只是让它作为 32 位应用程序运行。大多数用户甚至不会注意到差异。

截至当前 Xcode 版本(版本 5.0 (5A1412)):

【注】Xcode 的未来版本将允许您创建单个 app,该 app 在 iOS 6 及更高版本上支持 32 位运行时,并在 iOS 7 上支持 64 位运行时。 苹果来源

Apple 在 iOS 5.1 中修复了这个问题,因此,如果您将最小部署目标设置为 5.1,那么您可以创建一个 32/64 的胖二进制文件,该二进制文件将在 5.1 及更高版本中工作。我在 5.1 出来之前写了最初的问题。

最新更新