xcode 如何制作可在 iOS 5 到 7 上运行的 armv7 arm64 fat 二进制文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19482683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make a armv7 arm64 fat binary that will run on iOS 5 through 7?
提问by DavidPhillipOster
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 改变了指令集。由于单个程序可能需要在不止一种机器上运行,Apple 使用由名为“lipo”的工具构建的“fat 二进制文件”。您告诉 Xcode 多次编译您的程序,每种机器类型一次,然后 lipo 将它们绑定在一起。
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.
苹果最近推出了适用于 iOS 的第四个指令集。第一代手机使用Armv6,从3GS开始,我们有了Armv7,为Armv7s添加了一些新指令,现在,5S增加了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.
我喜欢我的程序在一系列操作系统下运行,所以我将 MIN_DEPLOYMENT_TARGET 设置为 5.0,这样 Apple 就会在 5.0 以后的机器上加载程序。但是当在当前版本的 Xcode 中尝试时,我收到一条错误消息,说这在 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:
好的,我设置了一个条件构建设置:对于 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
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.
并且该程序在 iOS 7 设备上运行良好,包括 Armv7 和 Arm64。一些诊断代码验证了在 Arm64 设备上运行时,实际上正在使用 Arm64 fork。
Running lipo on the binary reports that it has the expected architectures in it.
在二进制文件上运行 lipo 报告它具有预期的架构。
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."
但是,这是一个大问题:当我尝试在 iOS 5 设备上安装该应用程序时,Xcode 只是发出警报:“存在内部 API 错误。”
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.
我认为 iOS 5 和 iOS 6 中存在一个错误,因此它们不会忽略来自未来的分叉。加载器应该简单地忽略它不识别的叉。但这不是它的工作方式。
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.
Apple 永远不会修复 iOS 5。我认为 Apple 可能会在将应用程序加载到设备上时解决这个问题:让 Xcode 去除不需要的 fork,并重新签署(现在已修改的)二进制文件。同样,从 iTunes 下载可能会删除不需要的分叉并重新签名。但苹果不太可能这样做:苹果希望每个能升级到 iOS7 的人。对于无法升级的人,Apple 的解决方案是:购买新硬件。
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.
所以,我们被困住了。你可以在应用商店有一个支持5&6的标题,并发布一个针对7的更新,即fat armv7和arm64,这样你的iOS7用户就会得到fat一个,而你拥有5或6的用户将得到旧的,但你只能做一次。一旦您发布了 7 更新,您将永远无法再更新 5 和 6 更新。
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?
有没有解决的办法?我想要一个在 Armv7 和 Arm64 上运行的单个程序,以及用于 armv7 端的 iOS 5&6,用于 armv7 的 iOS 7 更难,它不支持 arm64 和 iOS 7 arm64,如何?
回答by Holly
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.
带有 64 位 sliver 的二进制文件无法在 iOS 5 上打开。这是操作系统级别的限制,没有办法绕过它。一般来说,不再需要支持 iOS 5,但我确信某个地方有人有正当理由支持它,希望他们能找到这个问题。
If you must support iOS 5, you have to remove the sliver for 64-bit. I This does notprevent 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.
如果您必须支持 iOS 5,则必须删除 64 位的条子。I 这不会阻止您的应用程序在 64 位系统上运行。它只是使它作为 32 位应用程序运行。大多数用户甚至不会注意到差异。
回答by David Wong
As of this current Xcode version (Version 5.0 (5A1412)):
截至目前的 Xcode 版本(版本 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
注意:Xcode 的未来版本将允许您创建一个应用程序,该应用程序在 iOS 6 及更高版本上支持 32 位运行时,并在 iOS 7 上支持 64 位运行时 。Apple Source
回答by DavidPhillipOster
Apple fixed this problem in iOS 5.1 so, if you set your min-deployment-target to 5.1, then you can make a 32/64 fat binary that will work in 5.1 on up. I wrote the original question before 5.1 came out.
Apple 在 iOS 5.1 中修复了这个问题,因此,如果您将 min-deployment-target 设置为 5.1,那么您可以制作一个 32/64 的胖二进制文件,它可以在 5.1 以上版本中运行。我在 5.1 出来之前写了原始问题。