一,前言
最近在幫朋友解決極光報錯的提示:「file was built for archive which is not the architecture being linked (i386)」時,涉及到Build Active Architecture Only設置問題。因此又從新溫習了一下,以便查詢。ios
二,關於Architectures 淺談
iOS項目打包,或者只是在項目裏面調用第三方靜態庫抑或是本身新建一個靜態庫,就要無可避免的和Architectures打交道。架構
* 什麼是Architectures?
architectures:n. 建築;架構(architecture的複數)。性能
* 關於Xcode中的Architectures 和 Valid Architectures
Architectures 和 Valid Architectures 在Targets面板的Build Settings下,以下圖紅框所示:測試
-
Architectures
指定工程支持的指令集的集合,若是設置多個architecture,則生成的二進制數據包會包含多個指令集代碼,體積會變大。ui
-
Valid Architectures
有效的指令集集合,Architectures與Valid Architectures 的交集來肯定最終的數據包包含的指令集代碼。
Xcode9.1建立的工程,Valid Architectures默認有這幾個:armv7 armv7s arm64,說明目前默認最低支持到iPhone5,也就是iOS8(iPhone5才能使用iOS8)spa
兩者的區別和聯繫:
大部分人都會被Architectures和Valid Architectures搞混淆。Valid Architectures表示的是你的項目所支持的處理器架構列表,是一個大的集合,而Architectures表示的是你的項目編譯的時候最終生成的二進制文件包含的處理器架構集合。固然若是你的Architectures超出了Valid Architectures的範圍,只能取Architectures和Valid Architectures的交集。通常來講,不須要修改Valid Architectures,你只要設置Architectures成你須要的架構版本就能夠了。若是你理解了這兩個概念,再回過頭來看看蘋果對Architectures和Valid Architectures的默認設置,Valid Architectures設置成:arm6四、armv七、armv7s,可是Architectures只設置成:armv七、arm64。這就是說,項目雖然支持市面上大部分手機的處理器架構版本,可是最終只比編譯了兩個版本。這也能夠理解,根據向下兼容原則,目前市面上大部分32位iOS設備都支持armv7,而64位設備都支持arm64, 對樣作即保證了高性能手機的運行性能不受影響,同時減少了生成包的大小,一箭雙鵰。調試
-
關於Armv7,Armv7s,Arm64
1. ARM code
ARM處理器,特色是體積小、低功耗、低成本、高性能, 因此幾乎全部手機處理器都基於ARM,在嵌入式系統中應用普遍 orm
2. ARM處理器指令集blog
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。