1. 程式人生 > >iOS之關於Architectures設定及Build Active Architecture Only編譯設定

iOS之關於Architectures設定及Build Active Architecture Only編譯設定

一,前言     

   最近在幫朋友解決極光報錯的提示:“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

     首先請注意上圖藍色框部分,選項裡面出現了好幾個ARM,ARM指的就是ARM處理器,它被普遍使用在嵌入式裝置中,例如手機、平板等。不同的裝置對應的處理器架構版本不同,裝置只會執行對應處理器版本的指令集。舉個栗子,iPhone5的處理器版本是armv7s,如果你最終只編譯了arm64版本,專案是不可能跑在iPhone5上面的,再或者你呼叫了一個只支援arm64的第三方靜態庫,而你的專案需要支援armv7和armv7s,這個時候你匯入這個第三方庫編譯就會報錯。但是有一點需要注意的就是向下相容原則,即你的專案只編譯了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。