如何制作将在iOS 5到7上运行的armv7 arm64 fat二进制文件? [英] How do I make a armv7 arm64 fat binary that will run on iOS 5 through 7?

查看:99
本文介绍了如何制作将在iOS 5到7上运行的armv7 arm64 fat二进制文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多年来,Apple已经改变了教学模式。由于单个程序可能需要在多种机器上运行,因此Apple使用由名为lipo的工具构建的胖二进制文件。你告诉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。现在程序编译,链接和脂肪。但是现在,由于其中一个编辑只是iOS 7.0,我得到一堆警告,我的程序包含对较旧操作系统的调用。我知道。这是故意的 - 所以程序将在那些旧系统上运行。在iOS 7系统上,不调用那些旧例程,而是在运行时,程序调用它们的现代替换。我可以让编译器停止抱怨:

  #pragma clang diagnostic push 
#pragma clang diagnostic ignored - Wdeprecated-declarations
//旧代码在这里。
#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下载可能会删除不需要的分叉并重新签名。但苹果不太可能这样做:Apple希望每个人都可以升级到iOS7。那些无法升级的苹果解决方案是:购买新硬件。



所以,我们陷入了困境。您可以在支持5& 6的应用程序商店中拥有一个标题,并发出7个胖胖armv7和arm64的更新,因此拥有iOS7的用户将获得胖,而拥有5或6的用户将会得到旧的,但你只能做一次。发布7更新后,您再也无法更新5& 6更新。



有没有解决方法?我想要一个在Armv7和Arm64上运行的程序,以及用于armv7方面的iOS 5和6,用于armv7的iOS 7以及不支持arm64的iOS 7和支持它的iOS 7 arm64,如何?

解决方案

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



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


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?

解决方案

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.

这篇关于如何制作将在iOS 5到7上运行的armv7 arm64 fat二进制文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆