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

Posted

技术标签:

【中文标题】如何制作将在 iOS 5 到 7 上运行的 armv7 arm64 fat 二进制文件?【英文标题】:How do I make a armv7 arm64 fat binary that will run on iOS 5 through 7? 【发布时间】:2013-10-20 20:47:34 【问题描述】:

多年来,Apple 已经更改了指令集。由于单个程序可能需要在不止一种机器上运行,Apple 使用由名为“lipo”的工具构建的“fat binaries”。您告诉 Xcode 多次编译您的程序,每种机器类型一次,然后 lipo 将它们绑定在一起。

Apple 最近推出了第四个 ios 指令集。第一部手机使用 Armv6,从 3GS 开始,我们有 Armv7,为 Armv7s 添加了一些新指令,现在,5S 添加了 Arm64。

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

好的,我设置了条件构建设置:对于 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。一段诊断代码验证当在 Arm64 设备上运行时,实际使用的是 Arm64 分支。

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

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

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

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

所以,我们陷入了困境。您可以在应用商店中拥有一个支持 5&6 的游戏,然后发布针对 7 的更新,即胖 armv7 和 arm64,这样您的 iOS7 用户将获得胖子,而您拥有 5 或 6 的用户将获得旧的,但你只能做一次。发布 7 更新后,您将永远无法再更新 5 和 6 更新。

有没有办法解决这个问题?我想要一个在 Armv7 和 Arm64 上运行的单个程序,以及用于 armv7 端的 iOS 5 和 6,用于 armv7 的 iOS 7 更难,不是 arm64 和支持它的 iOS 7 arm64,如何?

【问题讨论】:

我尝试使 exe 与 5.1.1 兼容,并在架构中包含 arm64(就像你一样),当我从 Xcode 5.1 运行时,我可以在 5.1.1 设备中运行应用程序,但是当我制作 ipa 文件时(安装程序)并尝试通过 iTunes 在设备中安装它在安装过程中无法“保持挂起”。你能找到这种情况的解决方案还是只留下 32 位选项? 【参考方案1】:

无法在 iOS 5 上打开 64 位 slivers 的二进制文件。这是操作系统级别的限制,无法解决。一般来说,应该没有必要再支持 iOS 5,但我确信某个地方的某个人有正当理由支持它,希望他们能找到这个问题。

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

【讨论】:

支持 iOS 5 的理由至少有 1500 万个。最初的 iPad 不能比 iOS 5 更高,Apple 卖出了超过 1500 万台。 根据this article,iOS 5 及之前的设备约占所有活跃设备的 7%。在大多数情况下,这不再值得支持,但必须由每个开发人员根据具体情况做出决定。 @Neal 你知道我是否仍然可以使用 Xcode 6 和 SDk 8.1 为 iOS 5.1.1 制作 exe 吗?我尝试放弃 arm64,但在验证我的 IPA 到 App Store 时收到错误。 应该可以,但是最近没试过。您可能遇到问题的一个地方是 ARMV7S 支持被删除。【参考方案2】:

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

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

【讨论】:

该来源并不表示单个二进制文件可以支持 iOS 5 和以前的带有 64 位 sliver 的二进制文件。当前的 Xcode 版本 (5.0) 已经支持使用 32 位和 64 位 sliver 进行构建。【参考方案3】:

Apple 在 iOS 5.1 中修复了这个问题,因此,如果您将 min-deployment-target 设置为 5.1,那么您可以制作一个 32/64 fat 二进制文件,该二进制文件将在 5.1 上运行。我在5.1出来之前写了原题。

【讨论】:

我无法正常工作。 Arm64 + iPad 1 @ iOS 5.1.1,不工作。你是怎么做到的?

以上是关于如何制作将在 iOS 5 到 7 上运行的 armv7 arm64 fat 二进制文件?的主要内容,如果未能解决你的问题,请参考以下文章

google-maps-sdk-ios - 适用于 iOS 的 Google 地图 1.4.3 的 arm 7/iphone 5 问题

模拟器不支持框架 - 制作虚拟框架

在 Windows 8 上的 Creator 中编译将在 Windows 7 上运行的 Qt 5 应用程序?

如何在带有 ios 7.0.2 的 iphone 5 上运行 xcode 5 项目

我如何重新编译C#程序以在ARM CPU上运行?

LinuxQt在arm上开发,程序运行出错,illegal instruction如何解决