上传App Store 报错 ERROR ITMS-90087:”Unsupported Architectures…”
问题原因:
有些第三方提供商为了方便开发者使用,在制作framework的时候经常把i386 x86_64 armv7 arm64 等几个平台合并到一起,但是上传App Store的应用包是不能包含i386 x86_64这两个。所以会出现上述错误。
相关描述
ARM
特点是体积小、低功耗、低成本、高性能,所以几乎所有手机处理器都基于ARM,在嵌入式系统中应用广泛。armv6 | armv7 | armv7s | arm64都是ARM处理器的指令集,这些指令集都是向下兼容的,例如armv7指令集兼容armv6,只是使用armv6的时候无法发挥出armv7的性能,从而会导致程序执行效率没有那么高。
设备指令集
指令集 | 描述 | 适用机型 |
---|---|---|
arm64 | 真机64位处理器 | iPhone5S(以及以上)| iPad Air| iPad mini2(iPad mini with Retina Display) |
armv7s | 真机32位处理器 | iPhone5|iPhone5C|iPad4(iPad with Retina Display) |
armv7 | 真机32位处理器 | iPhone3GS|iPhone4|iPhone4S|iPad|iPad2|iPad3(The New iPad)|iPad mini|iPod Touch 3G|iPod Touch4 |
armv6 | iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch(一般不需要去支持) | |
i386 | i386是针对intel通用微处理器32架构的 | 虚拟机: iPhone4s iPhone5 |
x86_64 | 针对x86架构的64位处理器 | 虚拟机: iPhone5S iPhone6 iPhone6S iPhone7 |
Xcode中指令集相关选项(Build Setting中)
(1) Architectures
指定工程被编译成可支持哪些指令集类型,支持的指令集越多,编译出包含指令集代码的数据包越多,生成二进制包就越大。
(2) Valid Architectures
限制可被支持的指令集的范围,也就是Xcode编译出来的二进制包类型最终从这些类型产生,最终编译出哪种指令集的包,将由Architectures与Valid Architectures 的交集来确定。
ep1
1 | Architectures: armv7, armv7s, arm64 |
ep2
1 | Architectures: armv6, armv7, armv7s |
ep3
1 | Architectures: armv7, armv7s, arm64 |
如果你对ipa安装包大小有要求,可以减少安装包的指令集的数量,这样就可以尽可能的减少包的大小。当然这样做会使部分设备出现性能损失。
在Xcode6里 Valid Architectures 默认为 Standard architectures(armv7,armv7s,arm64)
原因解释如下:
使用上述默认参数,则生成的包里面包含32位、64位两份代码,在iPhone5s( iPhone5s是64位 )下,会首选64位代码包,其余的iPhone( 其余iPhone都是32位的,iPhone5c也是32位 ),只能运行32位,但是包含这两种架构的代码包,只有运行在ios6,ios7系统上。也就是说,这种打包方式,对手机几乎没要求,但是对系统有要求,需要ios6以上。
而使用standard architectures (armv7,armv7s) 参数,则打的包里只有32位代码,iPhone5s的是64位,可兼容32位。但是会降低性能。其余的iPhone对32位代码也更没问题,而32位代码包,对系统也几乎也没什么限制。
要发挥iPhone5s的64位性能,就要包含64位包,那么系统最低要求为ios6。 如果要兼容ios5以及更低的系统,只能打32位的包,系统都能通用,但是会丧失iPhone5s的性能。
(3) Build Active Architecture Only
指是否只编译当前适用的指令集。当其值设置为YES,是为了debug的时候编译速度更快,它只编译当前的architecture版本(编译出的版本是向下兼容的),而设置为no时,会编译所有的版本。
1 | ep: |
所以,一般debug的时候可以选择设置为yes,release的时候要改为no,以适应不同设备。
如何拆分合并指令集
通过以上信息了解到,当我们做App的时候,为了追求高效率,并且减小包的大小,Build Active Architecture Only设置成YES,Architectures按Xcode默认配置,因为arm64向前兼容。但制作.a静态库就不同了,因为要保证兼容性,包括不同iOS设备以及模拟器运行不出错,所以结合当前行业情况,要做到最大的兼容性。
指令集查看命令
1 | lipo -info libWeChatSDK.a |
将lib库拆分出armv7、armv7s、i386类型的.a:
1.拆分单个包
1 | lipo libWeChatSDK.a -thin armv7 -output libWeChatSDK_armv7_final.a |
i386类型还可以使用下面命令拆分
1 | lipo -extract_family i386 -output libWeChatSDK_i386.a libWeChatSDK.a |
下面的命令并不是单独分出armv7版本,而是armv7和armv7s, 可用info命令验证
1 | lipo -extract_family armv7 -output libWeChatSDK_arm.a libWeChatSDK.a |
2.合并
合并armv7、armv7s、arm64
1 | lipo -output libWeChatSDK.a -create libWeChatSDK_arm.a libWeChatSDK_arm64_final.a |
3.多个应用的.a文件合并
用上面方法分别拆分处每个应用的armv7、armv7s、arm64等单个类型的.a库
一.分离出每个.a库的目标文件(.o)(在arm64目录下)
1 | ar -x ../libWeChatSDK_arm64_final.a |
二. 把相同类型静态库.o文件移到同一文件中,并合并出新的静态库(在arm64同级目录中执行)
1 | libtool -static -o libUniversal-arm64.a arm64/*.o |
其他同理,最终使用2合并命令生成通用静态库
以上内容参考以下文章: