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

Posted by 西维蜀黍 on 2017-04-30, Last Modified on 2024-05-07

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. 参考