1. 程式人生 > >IOS:armv7,armv7s,arm64,i386,x86

IOS:armv7,armv7s,arm64,i386,x86

一、概要
平時專案開發中,可能使用第三方提供的靜態庫.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).
要解決以上問題,就要了解一下Apple移動裝置處理器指令集相關的一些細節知識。
二、幾個重要概念
1、ARM
ARM處理器,特點是體積小、低功耗、低成本、高效能,所以幾乎所有手機處理器都基於ARM,在嵌入式系統中應用廣泛。

2、ARM處理器指令集
armv6|armv7|armv7s|arm64都是ARM處理器的指令集,這些指令集都是向下相容的,例如armv7指令集相容armv6,只是使用armv6的時候無法發揮出其效能,無法使用armv7的新特性,從而會導致程式執行效率沒那麼高。
還有兩個我們也很熟悉的指令集:i386|x86_64 是Mac處理器的指令集,i386是針對intel通用微處理器32架構的。x86_64是針對x86架構的64位處理器。所以當使用iOS模擬器的時候會遇到i386|x86_64,iOS模擬器沒有arm指令集。

3、目前iOS移動裝置指令集
arm64:iPhone5S| iPad Air| iPad mini2(iPad mini with Retina Display)
armv7s:iPhone5|iPhone5C|iPad4(iPad with Retina Display)
armv7:iPhone3GS|iPhone4|iPhone4S|iPad|iPad2|iPad3(The New iPad)|iPad mini|iPod Touch 3G|iPod Touch4
armv6 裝置: iPhone, iPhone2, iPhone3G, 第一代、第二代 iPod Touch(一般不需要去支援)
4、Xcode中指令集相關選項(Build Setting中)
(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.
指定工程被編譯成可支援哪些指令集型別,而支援的指令集越多,就會編譯出包含多個指令集程式碼的資料包,對應生成二進位制包就越大,也就是ipa包會變大。
(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.
限制可能被支援的指令集的範圍,也就是Xcode編譯出來的二進位制包型別最終從這些型別產生,而編譯出哪種指令集的包,將由Architectures與Valid Architectures(因此這個不能為空)的交集來確定,例如:
比如,你的Valid Architectures設定的支援arm指令集版本有:armv7/armv7s/arm64,對應的Architectures設定的支援arm指令集版本有:armv7s,這時Xcode只會生成一個armv7s指令集的二進位制包。
再比如:將Architectures支援arm指令集設定為:armv7,armv7s,對應的Valid Architectures的支援的指令集設定為:armv7s,arm64,那麼此時,XCode生成二進位制包所支援的指令集只有armv7s

在Xcode6.1.1裡的 Valid Architectures 設定裡, 預設為 Standard architectures(armv7,arm64),如果你想改的話,自己在other中更改。

原因解釋如下:
使用 standard architectures (including 64-bit)(armv7,arm64) 引數,則打的包裡面有32位、64位兩份程式碼,在iPhone5s( iPhone5s的cpu是64位的 )下,會首選執行64位程式碼包, 其餘的iPhone( 其餘iPhone都是32位的,iPhone5c也是32位 ),只能執行32位包,但是包含兩種架構的程式碼包,只有執行在ios6,ios7系統上。
這也就是說,這種打包方式,對手機幾乎沒要求,但是對系統有要求,即ios6以上。
而使用 standard architectures (armv7,armv7s) 引數, 則打的包裡只有32位程式碼, iPhone5s的cpu是64位,但是可以相容32位程式碼,即可以執行32位程式碼。但是這會降低iPhone5s的效能。 其餘的iPhone對32位程式碼包更沒問題, 而32位程式碼包,對系統也幾乎也沒什麼限制。
所以總結如下:

要發揮iPhone5s的64位效能,就要包含64位包,那麼系統最低要求為ios6。 如果要相容ios5以及更低的系統,只能打32位的包,系統都能通用,但是會喪失iPhone5s的效能。
(3)Build Active Architecture Only
指定是否只對當前連線裝置所支援的指令集編譯
當其值設定為YES,這個屬性設定為yes,是為了debug的時候編譯速度更快,它只編譯當前的architecture版本,而設定為no時,會編譯所有的版本。 編譯出的版本是向下相容的,連線的裝置的指令集匹配是由高到低(arm64 > armv7s > armv7)依次匹配的。比如你設定此值為yes,用iphone4編譯出來的是armv7版本的,iphone5也可以執行,但是armv6的裝置就不能執行。 所以,一般debug的時候可以選擇設定為yes,release的時候要改為no,以適應不同裝置。
1)
Architectures: armv7, armv7s, arm64
ValidArchitectures: armv6, armv7s, arm64
生成二進位制包支援的指令集: arm64
2)
Architectures: armv6, armv7, armv7s
Valid Architectures: armv6, armv7s, arm64
生成二進位制包支援的指令集: armv7s
3)
Architectures: armv7, armv7s, arm64
Valid Architectures: armv7,armv7s
這種情況是報錯的,因為允許使用指令集中沒有arm64。