1、概要
平時(shí)項(xiàng)目開發(fā)中,可能使用第三方提供的.a靜態(tài)庫,如果.a提供方技術(shù)不成熟,使用的時(shí)候就會(huì)出現(xiàn)問題,例如:
在真機(jī)上編譯報(bào)錯(cuò),No architectures to compile for(ONLY_ACTIVE_ARCH=YES,active arch=x86_64,VALID_ARCHS=i386)
在模擬器上編譯報(bào)錯(cuò):No architectures to compile for(ONLY_ACTIVE_ARCH=YES,active arch=armv7s,VALID_ARCHS=armv7 armv6)
要解決以上問題,就要了解一下Apple移動(dòng)設(shè)備處理器指令集相關(guān)的一些細(xì)節(jié)知識(shí)。
二、幾個(gè)重要概念
1、ARM
ARM處理器,特點(diǎn)是體積小,低功耗,低成本,高性能,所以幾乎所有手機(jī)處理器都基于ARM,在嵌入式系統(tǒng)中應(yīng)用廣泛。
2、ARM處理器指令集
armv6 | armv7 | armv7s | arm64都是ARM處理器的指令集,這些指令集都是向下兼容的,例如armv7指令集兼容armv6,只是armv6的時(shí)候無法發(fā)揮出其性能,無法使用armv7的新特性,從而會(huì)導(dǎo)致程序執(zhí)行效率沒那么高。
還有兩個(gè)我們也很熟悉的指令集,i386 | x86_64是Mac處理器的指令集,i386是針對(duì)intel通用微處理器32架構(gòu)的。x86_64是針對(duì)x86架構(gòu)的64位處理器。所以當(dāng)使用iOS模擬器的時(shí)候會(huì)遇到i386 | x86_64,iOS模擬器沒有arm指令集。
3、目前iOS移動(dòng)設(shè)備指令集
arm64:iPhone5s | iPad Air | iPad mini2(iPad mini with Retina Display)
armv7s:iPhone5 | iPhone 5C | iPad4(iPad with Retina Dispaly)
armv7:iPhone3GS | iPhone4 | iPhone4S | iPad | iPad2 | iPad3(The New iPad) | iPad mini | iPod Touch 3G | iPod Touch 4
armv6設(shè)備:iPhone,iPhone2,iPhone3G,第一代、第二代iPod Touch(一般不需要去支持)
4、Xcode中指令集相關(guān)選項(xiàng)(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.
指定工程被編譯成可支持哪些指令集類型,而支持的指令集越多,就會(huì)編譯出包含多個(gè)指令集代碼的數(shù)據(jù)包,對(duì)應(yīng)生成二進(jìn)制包就越大,也就是ipa包會(huì)變大。
(2)Valid Architectures
Space-separated list of identifiers.Specfies the architecture for which the binary may be build.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 genetates no binary.
限制可能被支持的指令集的范圍,也就是Xcode編譯出來的二進(jìn)制包類型最終從這些類型產(chǎn)生,而編譯出哪種指令集的包,將由Architectures與Valid Architectures(因此這個(gè)不能為空)的交集來確定,例如:比如,你的Valid Architectures設(shè)置的支持arm指令集版本有:armv7/armv7s/arm64,對(duì)應(yīng)的Architectures設(shè)置的支持arm指令集版本有:armv7s,這時(shí)Xcode只會(huì)生成一個(gè)armv7s指令集的二進(jìn)制包。
再比如:將Architectures支持arm指令集設(shè)置為:armv7,armv7s,對(duì)應(yīng)的Valid Architectures的支持的指令集設(shè)置為:armv7s,arm64,那么此時(shí),Xcode生成二進(jìn)制包所支持的指令集只有armv7s
在Xcode6.1.1里的Valid Architectures設(shè)置里,默認(rèn)為Standard architectures(armv7,arm64),如果你想改的話,自己在other中更改。
原因解析如下:
使用standard architectures(including 64-bit))(armv7,arm64)參數(shù),則打的包里面有32位、64位兩份代碼,在iPhone5s(iPhone5s的cpu是64位的)下,會(huì)首選運(yùn)行64位代碼包,其余的iPhone(其余iPhone都是32位的,iPhone5c也是32位的),只能運(yùn)行32位包,但是包含兩種架構(gòu)的代碼包,只有運(yùn)行在iOS6,iOS7系統(tǒng)上。
這也就是說,這種打包方式,對(duì)手機(jī)幾乎沒要求,但是對(duì)系統(tǒng)有要求,即iOS6以上。
而使用standard architectures(armv7,armv7s)參數(shù),則打的包里只有32位代碼,iPhone5s的cpu是64位,但是可以兼容32位代碼,即可以運(yùn)行32位代碼。但是這會(huì)降低iPhone5s的性能。其余的iPhone對(duì)32位代碼包更沒問題,而32位代碼包,對(duì)系統(tǒng)也幾乎也沒什么限制。
所以總結(jié)如下:
要發(fā)揮iPhone5s的64位性能,就要包含64位包,那么系統(tǒng)最低要求為iOS6。如果要兼容iOS5以及更低的系統(tǒng),只能打32位的包,系統(tǒng)都能通用,但是會(huì)喪失iPhone5s的性能。
(3)Build Active Architecture Only
指定是否只對(duì)當(dāng)前連接設(shè)備所支持的指令集編譯
當(dāng)其值設(shè)置為YES,這個(gè)屬性設(shè)置為yes,是為了debug的時(shí)候編譯速度更快,它只編譯當(dāng)前的architecture版本,而設(shè)置為NO時(shí),會(huì)編譯所有的版本。編譯出的版本是向下兼容的,連接的設(shè)備的指令集匹配是由高到低(arm64 > armv7s > armv7)依次匹配的。比如你設(shè)置此值為yes,用iPhone4編譯出來的版本是armv7版本的,iPhone5也可以運(yùn)行,但是armv6的設(shè)備就不能運(yùn)行。所以,一般debug的時(shí)候可以選擇設(shè)置為yes,release的時(shí)候要改為NO,以適應(yīng)不同設(shè)備。
(1)
Architectures:armv7,armv7s,arm64
Valid Architectures:armv6,armv7s,arm64
生成二進(jìn)制包支持的指令集:arm64
(2)
Architectures:armv6,armv7,armv7s
Valid Architectures:armv6,armv7s,arm64
生成的二進(jìn)制包支持的指令集:armv7s
(3)
Architectures:armv7,armv7s,arm64
Valid Architectures:armv7,armv7s
這種情況是報(bào)錯(cuò)的,因?yàn)樵试S使用指令集中沒有arm64
注:如果你對(duì)ipa安裝包大小有要求,可以減少安裝包的指令集的數(shù)量,這樣就可以盡可能的減少包的大小。當(dāng)然這樣做會(huì)使部分設(shè)備出現(xiàn)性能損失,當(dāng)然在普通應(yīng)用中這點(diǎn)體現(xiàn)幾乎感覺不到,至少不會(huì)威脅到用戶體驗(yàn)。
三、制作靜態(tài)庫.a是指令集選擇
現(xiàn)在回歸到正題,如何制作一個(gè)“沒有問題”的.a靜態(tài)庫,通過以上信息了解到,當(dāng)我們做App的時(shí)候,為了追求高效率,并且減小包的大小,Build Active Architecture Only設(shè)置為YES,Architectures按Xcode默認(rèn)配置就可以,因?yàn)閍rm64向前兼容。但制作.a靜態(tài)庫就不同了,因?yàn)橐WC兼容性,包括不同iOS設(shè)備以及模擬器運(yùn)行不出錯(cuò),所以結(jié)合當(dāng)前行業(yè)情況,要做到最大的兼容性。
Valid Architectures設(shè)置為:armv7 | armv7s | arm64 | i386 | x86_64
Architectures設(shè)置不變(或根據(jù)你需要):armv7 | arm64
然后分別選擇iOS設(shè)備和模擬器進(jìn)行編譯,最后找到相關(guān)的.a進(jìn)行合包,使用lipo -create 真機(jī)庫.a的路徑 模擬器庫.a的路徑 -output 合成庫的名字.a(詳情可以參考http://blog.csdn.net/lizhongfu2013/article/details/12648633)這樣就制作了一個(gè)通用的靜態(tài)庫.a