一、ARM架构
ARM架构过去称作进阶精简指令集机器(Advanced RISC Machine,更早称作:Acorn RISC Machine),是一个32位精简指令集(RISC)处理器架构,ARM处理器非常适用于移动通讯领域,符合其主要设计目标为低耗电的特性。
ARM和Intel处理器的第一个区别是,前者使用精简指令集(RISC),而后者使用复杂指令集(CISC)。
二、ARM处理器指令集
ARM指令集是指计算机ARM操作指令系统。
armv6、armv7、armv7s、arm64、arm64e都是arm处理器的指令集,所有指令集原则上都是向下兼容的。比如,你的设备是armv7s指令集,那么它也可以兼容运行比armv7s版本低的指令集:armv7、armv6。Xcode4.5起不再支持armv6。
苹果A7处理器支持两个不同的指令集:32位ARM指令集(armv6|armv7|armv7s)和64位ARM指令集(arm64)。
i386|x86_64 是Mac处理器的指令集。
i386通常被用来作为对Intel 32位微处理器的统称。X86-64可在同一时间内处理64位的整数运算,并兼容X86-32架构,x86_64是针对x86架构的64位处理器。当使用iOS模拟器的时候会遇到i386|x86_64,iOS模拟器没有运行arm指令集,编译运行的是x86指令集,所以,只有在iOS设备上,才会执行设备对应的arm指令集。
三、iOS设备支持的指令集
armv6:
iPhone, iPhone 3G, iPod 1G/2G
armv7:
iPhone 3GS, iPhone 4, iPhone 4S, iPod 3G/4G/5G, iPad, iPad 2, iPad 3, iPad Mini
armv7s:
iPhone 5, iPhone 5c, iPad 4
arm64:
iPhone X,iPhone 8(Plus),iPhone 7(Plus),iPhone 6(Plus),iPhone 6s(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)
arm64e:
iPhone XS\XR\XS Max
四、Xcode->Build setting
1. Architectures
指定工程被编译成支持哪些指令集类型,而支持的指令集越多,就会编译出很多个指令集代码的数据包,对应生成二进制包就越大,也就是ipa包越大。
现在XCode->build setting 中Architectures的默认值是Standard architectures- $(ARCHS-STANDARD), $(ARCHS-STANDARD)的值如下图所示:
地址:https://pewpewthespells.com/blog/buildsettings.html#current_arch
2、Valid Architectures
该编译项指定可能支持的指令集,该列表和Architectures列表的交集,将是Xcode最终生成二进制包所支持的指令集。
比如,你的Valid Architectures设置的支持arm指令集版本有:armv7/armv7s/arm64,对应的Architectures设置的支持arm指令集版本有:arm64,这时Xcode只会生成一个arm64指令集的二进制包。
减少安装包中的指令集数据包可以减小打包ipa的大小。
3、Build Active Architecture Only:
指明是否只编译当前连接设备所支持的指令集。
默认Debug的时候设置为YES,Release的时候设置为NO。设置为YES是只编译当前的architecture版本,生成的包只包含当前连接设备的指令集代码。设置为NO,则生成的包包含所有的指令集代码(上面的Valid Architectures跟Architectures的交集)。因此为了调试速度更快,则Debug应该设置为YES。
特殊:设置此值为YES,如果连接的设备是arm64的( iPhone 5s,iPhone6(plus)等),则Valid Architecture 中必须包含arm64, 否则编译会报错(报错的内容在下面常见问题中)。
五、常见错误
1. 编译报错 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
问题起因:active architecture(当前连接设备的指令集)为64位指令集,但是valid architecture只包含32位指令集
解决方法:valid architecture增加arm64 (常见的一些帖子的解决方案是把Build Active Architecture Only设置为NO,这是个简单粗暴的解决办法,在Debug过程中也会生成包含所有指令集的代码,更何况现在官方强制必须支持64位,故不建议采纳)
2. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=i386, VALID_ARCHS=x86_64).
问题起因:跟上个问题同理,只不过连接的设备指令集是32位指令集,但是valid architecture只包含64位指令集
解决办法:valid architecture增加armv7
3. 导入静态库后编译报错为
问题起因:
1:可能是静态库中不包含这个类。
2:静态库工程可能没有链接到应用。
3:可能是因为静态库(.a)为真机版本,不包含模拟器版本(i386)。
解决办法:
1:查看静态库里面是否存在这个类。
2:Build Phases中没有添加Link Binary With Libraries 中添加此静态库。
3:把调试目标换成真机 或者 导入一个模拟器版本跟真机版本合并的版本
同理如果导入的库是模拟器版本而用真机调试也会报错,所以导入一个通用的版本是目前来讲最好的办法。
for (ONLY_ACTIVE_ARCH=YES, active arch=arm64, VALID_ARCHS=armv7 armv7s)
当Build Active Architecture Only起作用时:连接的手机指令集匹配是由高到低(arm64 > armv7s > armv7)依次匹配的。
for (ONLY_ACTIVE_ARCH=YES, active arch=armv7s, VALID_ARCHS=armv7 arm64)
同样的,若Architectures列表为armv7,则会选取armv7作为目标指令集,若Valid Architectures列表中包含了armv7指令集,则能够成功生成二进制包,其支持的指令集只有armv7,若Valid Architectures列表中不包含armv7,则编译失败。
参考:
http://www.cocoachina.com/industry/20140527/8566.html
http://www.cocoachina.com/ios/20140915/9620.html