【iOS】 Apple移动设备处理器指令集与Xcode指令集相关设置

Posted by 西维蜀黍 on 2017-04-30, Last Modified on 2021-10-02

1.ARM

ARM处理器,因为其低功耗和小尺寸而闻名,几乎所有的手机处理器都基于ARM,其在嵌入式系统中的应用非常广泛,它的性能在同等功耗产品中也很出色。

ARMv6、ARMv7、ARMv7s、ARM64都是ARM处理器的指令集所有指令集原则上都是向下兼容的

如 iPhone4S 的CPU默认指令集为ARMv7指令集,但iPhone4S 的 CPU 同时也兼容ARMv6指令集(也就是,只包含 ARMv6 指令集的.ipa同样也可以运行在 iPhone4S 上)。只是使用 ARMv6 指令集运行时无法充分发挥其性能,即无法使用ARMv7指令集中的新特性。 同理,iPhone5的处理器标配 ARMv7s 指令集,同时也支持 ARMv7 指令集,只是无法进行相关的性能优化,从而导致程序的执行效率没那么高。

需要注意的是iOS模拟器没有运行ARM指令集,编译运行的是x86指令集,所以,只有在iOS设备上,才会执行设备对应的ARM指令集。

2.设备默认指令集

从 iPhone 6之后出的iPhone、iPad、iPod touch均为arm64架构。

3.Xcode中与指令集相关的选项

【Xcode】 - 【Build Setting】中指令集相关设置:

常用的架构项:

  • armv7
  • armv7s
  • arm64
  • i386
  • x86_64

从Xcode4.5开始,就不再支持armv6指令集,所以列表中写了也是白写。

(1)Architectures

官方文档描述:

Space-separated list of identifiers. Specifies the architectures (ABIs, processor models) to which the binary is targeted. When this build setting specifies more than one architecture, the generated binary may contain object code for each of the specified architectures.

Architectures指定工程编译出的二进制包支持哪些指令集类型。 如果选择多个指令集,就会编译出包含多个指令集代码的数据包,对应生成二进制包就越大。

(2)Valid Architectures

官方文档描述:

Space-separated list of identifiers. Specifies the architectures for which the binary may be built. During the build, this list is intersected with the value of ARCHS build setting; the resulting list specifies the architectures the binary can run on. If the resulting architecture list is empty, the target generates no binary.

Valid Architectures指定哪些指令集允许被支持,其实这个设置主要处理的是指令集向下兼容问题。

而最后编译出包含哪些指令集的包,将由Architectures与Valid Architectures 设置项的交集来确定。

比如,将Architectures支持arm指令集设置为:armv7armv7s,对应的Valid Architectures的支持的指令集设置为:armv7sarm64,那么此时,Xcode生成二进制包所支持的指令集只有 armv7s

(3)Build Active Architecture Only

官方文档描述:

Boolean value. Specifies whether the product includes only object code for the native architecture.

Build Active Architecture Only指定是否只对当前连接设备所使用的指令集编译。

当设置为 yes 时,它只编译当前连接设备对应的architecture版本(编译速度较快);而当设置为 no 时,会编译对应所有architecture的版本。

所以,一般debug模式下可设置为yes,release模式下设置为no。

(4)各种小问题

a.向下兼容问题

** ARMv6|ARMv7|ARMv7s|ARM64都是ARM处理器的指令集(指令集版本由高到低(ARM64 > ARMv7s > ARMv7 > ARMv6)),这些指令集都是向下兼容的。**

这里的向下兼容是指:包含高指令集的 .ipa可以运行在只支持低版本指令集的Apple设备上。 比如编译出来的二进制包只包括 ARMv7 指令集,在iPhone5(ARMv7s)中是可以运行,但是在iPhone 1(ARMv6)上就不能运行了。

b.【.a】文件支持的架构类型问题

平时项目开发中,可能使用第三方提供的静态库.a,如果.a提供方技术不成熟,使用的时候就会出现问题,例如:

  • 在真机上编译报错:No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
  • 在模拟器上编译报错:No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv7s, VALID_ARCHS=armv7 armv6).

原因其实是,我的项目被设置为最终编译时包含某种指令集对应的二进制代码,然而这个第三方.a库中并没有包含这种特定的指令集。

(5)总结

说了这么多,或许你不想了解这么多细节,只希望知道【最佳实践的设置】,结论如下:

(1)对于普通 App 开发者,ArchitecturesValid ArchitecturesBuild Active Architecture Only的设置按项目初始时的默认设置即可,不要修改他们。默认值如下:

(2)对于第三方库的开发者,需要保证在.a or .framework中包含 ARMv7、ARMv7s、ARM64 3种指令集对应的二进制代码。

4.参考