iOS開發~製做同時支持armv7,armv7s,arm64,i386,x86_64的靜態庫.a以及 FrameWork 的建立

 

armv7,armv7s,arm64,i386,x86_64 詳解php

1、概要html

平時項目開發中,可能使用第三方提供的靜態庫.a,若是.a提供方技術不成熟,使用的時候就會出現問題,例如:ios

在真機上編譯報錯: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).iphone

要解決以上問題,就要了解一下Apple移動設備處理器指令集相關的一些細節知識。ide

 

2、幾個重要概念post

一、ARM性能

ARM處理器,特色是體積小、低功耗、低成本、高性能,因此幾乎全部手機處理器都基於ARM,在嵌入式系統中應用普遍。網站

 

二、ARM處理器指令集ui

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指令集。

 

三、目前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(通常不須要去支持)

 

四、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。

注:若是你對ipa安裝包大小有要求,能夠減小安裝包的指令集的數量,這樣就能夠儘量的減小包的大小。固然這樣作會使部分設備出現性能損失,固然在普通應用中這點體現幾乎感受不到,至少不會威脅到用戶體檢。

 

3、製做靜態庫.a是指令集選擇

如今迴歸到正題,如何製做一個「沒有問題」的.a靜態庫,經過以上信息瞭解到,當咱們作App的時候,爲了追求高效率,而且減少包的大小,Build Active Architecture Only設置成YES,Architectures按Xcode默認配置就能夠,由於arm64向前兼容。但製做.a靜態庫就不一樣了,由於要保證兼容性,包括不一樣iOS設備以及模擬器運行不出錯,因此結合當前行業狀況,要作到最大的兼容性。

ValidArchitectures設置爲:armv7|armv7s|arm64|i386|x86_64 

Architectures設置不變(或根據你須要):  armv7|arm64

而後分別選擇iOS設備和模擬器進行編譯,最後找到相關的.a進行合包,使用lipo -create 真機庫.a的路徑 模擬器庫.a的的路徑 -output 合成庫的名字.a(詳情能夠參考http://blog.csdn.NET/lizhongfu2013/article/details/12648633)

這樣就製做了一個通用的靜態庫.a

 

  二 .a 與 FrameWork 合併技巧
 
 
查看.a 和 FrameWork 的適配機型  
 
lipo -create Debug-iphoneos/libMJRefresh.a Debug-iphonesimulator/libMJRefresh.a -output libMJRefresh.a
lipo -create /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-ctegiztcjikewoeprxxtmryzetfa/Build/Products/Release-iphoneos/libFMDB.a /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-ctegiztcjikewoeprxxtmryzetfa/Build/Products/Release-iphonesimulator/libFMDB.a -output /Users/harvey/Desktop/libFMDB.a
lipo -create /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-clvayfrjgytqrbdkyqrtcjkxfeuz/Build/Products/Release-iphonesimulator/FMDB.framework/FMDB /Users/harvey/Library/Developer/Xcode/DerivedData/FMDB-clvayfrjgytqrbdkyqrtcjkxfeuz/Build/Products/Release-iphoneos/Release-iphoneos.framework/FMDB -output /Users/harvey/Desktop/FMDB
Architectures in the fat file: /Users/kunkkaqi/Desktop/TestFrameWork.framework/TestFrameWork.lipo are: i386 armv7 armv7s x86_64 arm64 
 
 
參考連接:
相關文章
相關標籤/搜索