一,前言
最近在幫朋友解決極光報錯的提示:“file was built for archive which is not the architecture being linked (i386)”時,涉及到Build Active Architecture Only設置問題。所以又重新溫習了一下,以便查詢。
二,關於Architectures 淺談
iOS項目打包,或者只是在項目里面調用第三方靜態庫抑或是自己新建一個靜態庫,就要無可避免的和Architectures打交道。
* 什么是Architectures?
architectures:n. 建築;架構(architecture的復數)。
* 關於Xcode中的Architectures 和 Valid Architectures
Architectures 和 Valid Architectures 在Targets面板的Build Settings下,如下圖紅框所示:
-
Architectures
指定工程支持的指令集的集合,如果設置多個architecture,則生成的二進制數據包會包含多個指令集代碼,體積會變大。
-
Valid Architectures
有效的指令集集合,Architectures與Valid Architectures 的交集來確定最終的數據包包含的指令集代碼。
Xcode9.1創建的工程,Valid Architectures默認有這幾個:armv7 armv7s arm64,說明目前默認最低支持到iPhone5,也就是iOS8(iPhone5才能使用iOS8)
二者的區別和聯系:
大部分人都會被Architectures和Valid Architectures搞混淆。Valid Architectures表示的是你的項目所支持的處理器架構列表,是一個大的集合,而Architectures表示的是你的項目編譯的時候最終生成的二進制文件包含的處理器架構集合。當然如果你的Architectures超出了Valid Architectures的范圍,只能取Architectures和Valid Architectures的交集。一般來說,不需要修改Valid Architectures,你只要設置Architectures成你需要的架構版本就可以了。如果你理解了這兩個概念,再回過頭來看看蘋果對Architectures和Valid Architectures的默認設置,Valid Architectures設置成:arm64、armv7、armv7s,但是Architectures只設置成:armv7、arm64。這就是說,項目雖然支持市面上大部分手機的處理器架構版本,但是最終只比編譯了兩個版本。這也可以理解,根據向下兼容原則,目前市面上大部分32位iOS設備都支持armv7,而64位設備都支持arm64, 對樣做即保證了高性能手機的運行性能不受影響,同時減小了生成包的大小,一舉兩得。
-
關於Armv7,Armv7s,Arm64
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的ARM處理器指令集及其支持的設備:
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.Mac處理器的指令集:
i386:iPhone4s~5
x86_64:iPhone5s~
5.Mac處理器的指令集:
i386是針對intel通用微處理器32位處理器
x86_64是針對x86架構的64位處理器模擬器32位處理器測試需要i386架構,
模擬器64位處理器測試需要x86_64架構,
真機32位處理器需要armv7,或者armv7s架構,
真機64位處理器需要arm64架構。
-
Build Active Architectures Only配置
該編譯項用於設置是否只編譯當前使用的設備對應的arm指令集
1. 設置成YES時,你連上一個armv7指令集的設備,就算你的Valid Architectures和Architectures都設置成armv7/armv7s/arm64,還是依然只會生成一個armv7指令集的二進制包.(該選項起作用的前提是你的Xcode必須成功連接了調試設備! 如果你沒有任何活躍設備,即Xcode沒有成功連接調試設備,就算該設置項設置成YES依然還會編譯Valid Architectures和Architectures指定的二進制包.)
2. 通常情況下,該編譯選項在Debug模式都設成YES,Release模式都設成NO
Debug和Release下的設置:
這個屬性主要用在Debug的時候。根據字面意思,就是說只編譯你當前連接設備(活躍狀態)的處理器版本。這個屬性不需要修改,Xcode的默認設置就是Debug為Yes,Release 為No。
Debug模式設置為Yes,編譯的時候只編譯成當前連接設備的處理器版本,會大大縮短編譯時間。
Release模式設置為No,你要適配市面上大部分手機,如果Release你還設置成Yes,那么你生成的安裝包只能安裝在你當前連接設備的編譯類型的手機上。當然,這也是你Release編譯所花的時間要大大超過Debug的原因。 -
Supported Platform 配置
指定支持的設備平台
-
Base SDK配置
Base SDK-->指的是當前編譯所用的SDK 版本
Base SDK設置會引導編譯器使用該版本的SDK編譯和構建應用,也就是說,它會直接控制應用使用哪些API. 默認情況下,Xcode中創建的新工程總是使用最新版本的SDK,而蘋果會處理API的廢棄,如下圖:
三,總結
* standard architectures
使用 standard architectures (including 64-bit)(armv7,arm64) 參數,則打的包里面有32位、64位兩份代碼,在iPhone5s( iPhone5s的cpu是64位的 )下,會首選運行64位代碼包, 其余的iPhone( 其余iPhone都是32位的,iPhone5c也是32位 ),只能運行32位包,但是包含兩種架構的代碼包,只有運行在ios6以上的系統上。
使用 standard architectures (armv7,armv7s) 參數, 則打的包里只有32位代碼, iPhone5s的cpu是64位,但是可以兼容32位代碼,即可以運行32位代碼。但是這會降低iPhone5s的性能。 其余的iPhone對32位代碼包更沒問題, 而32位代碼包,對系統也幾乎也沒什么限制。
所以:
要發揮iPhone5s的64位性能,就要包含64位包,那么系統最低要求為ios6。 如果要兼容ios5以及更低的系統,只能打32位的包,系統都能通用,但是會喪失iPhone5s的性能。當然這樣做會使部分設備出現性能損失,當然在普通應用中這點體現幾乎感覺不到,至少不會威脅到用戶體檢。
* 靜態庫的制作
制作靜態庫.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。