Xcode裡面指令集設定的理解和總結
基本概念
-
ARM
ARM架構,是一種低成本、高效能、低耗電處理器架構,目前廣泛的在行動通訊領域中使用。
-
ARM處理器指令集
蘋果A7處理器支援兩個不同的指令集:32位ARM指令集(armv6|armv7|armv7s)和64位ARM指令集(arm64)。
i386|x86_64 是Mac處理器的指令集,i386是針對intel通用微處理器32架構的。x86_64是針對x86架構的64位處理器。當使用iOS模擬器的時候會遇到i386|x86_64,iOS模擬器沒有arm指令集。 -
目前iOS移動裝置指令集
ARMv8/ARM64: iPhone 6(Plus), iPhone 5s, iPad Air(2), Retina iPad Mini(2,3)
ARMv7s: iPhone 5, iPhone 5c, iPad 4
ARMv7: iPhone 3GS, iPhone 4, iPhone 4S, iPod 3G/4G/5G, iPad, iPad 2, iPad 3, iPad Mini
ARMv6: iPhone, iPhone 3G, iPod 1G/2G
“Build Setting” 中Architecture詳解
-
Architectures
指定工程支援的指令集的集合,如果設定多個architecture,則生成的二進位制資料包會包含多個指令集程式碼,體積會變大。
-
Valid Architectures
有效的指令集集合,Architectures與Valid Architectures 的交集來確定最終的資料包包含的指令集程式碼。
-
Build Active Architecture Only
指定是否只對當前連線裝置所支援的指令集編譯,預設Debug的時候設定為YES,Release的時候設定為NO。設定為YES是隻編譯當前的architecture版本,生成的包只包含當前連線裝置的指令集程式碼。設定為NO,則生成的包包含所有的指令集程式碼(上面的Valid Architectures跟Architectures的交集)。因此為了除錯速度更快,則Debug應該設定為YES。
特殊:設定此值為YES,如果連線的裝置是arm64的( iPhone 5s,iPhone6(plus)等),則Valid Architecture 中必須包含arm64, 否則編譯會報錯(報錯的內容在下面常見問題中)。
總結一下,按照新版Xcode6.1.1的預設設定就沒有任何問題,之前的Xcode版本開發的專案也建議升級到Xcode6.1.1,同樣按照如下配置:
- Architectures 預設設定為 Standard architectures(armv7,arm64) 。(之前的Xcode版本中預設設定還包括armv7s,現在去掉了,估計是因為armv7s相較armv7優化不大,能向下相容,而設定後還會增大二進位制包的大小)
- Valid Architectures 預設設定為 armv7 armv7s arm64。
- Build Active Architecture Only:預設Debug的時候設定為YES,Release的時候設定為NO。
App適配64位
-
為什麼要適配64位?
1: 蘋果官方要求: 2015年2月1日起,提交到AppStore的新應用必須支援64bit,6月1日起,更新的app也必須支援64bit。詳見官方文件。
2: 為了提升效能:目前A7使用的是ARM V8架構,除了使用64位的地址匯流排和64位的暫存器以外,還增加了暫存器的數量,目前A7中的整數和浮點數暫存器是A6的兩倍。暫存器的增加提高了程式的執行速度。詳見官方文件。再者,64位系統為了相容32位的程式,64位的iOS系統中帶有兩套Framework,一套32位的,一套64位的。當64位的iOS系統執行原來的32位程式時,系統會呼叫32位的Framework作為底層支撐,當系統執行64位程式時,系統會呼叫64位的Framework作為底層支撐,所以如果app不做64位適配的話,系統會呼叫32位Framework,消耗記憶體增多,執行速度會變慢。
-
如何適配64位?
1:Xcode版本號>5.0.1。(建議升級到最新版本)
2:minimum deployment target > 5.1.1。
3:按照上述Xcode6的預設配置進行配置,其他Xcode版本最好也進行如此配置。
4:執行測試程式碼,解決編譯warnings and errors,對照本文件或者官方文件 64-Bit Transition Guide for Cocoa Touch對相應地方做出修改。(編譯器不能告訴我們一切)
5:在真實的64-bit機器上測試。
6:使用Instruments檢視記憶體使用問題。
關於Architecture的常見問題
1. 編譯報錯 No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=x86_64, VALID_ARCHS=i386).
問題起因:active architecture(當前連線裝置的指令集)為64位指令集,但是valid architecture只包含32位指令集
解決方法:valid architecture增加arm64 (常見的一些帖子的解決方案是把Build Active Architecture Only設定為NO,這是個簡單粗暴的解決辦法,在Debug過程中也會生成包含所有指令集的程式碼,更何況現在官方強制必須支援64位,故不建議採納)
2. No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=i386, VALID_ARCHS=x86_64).
問題起因:跟上個問題同理,只不過連線的裝置指令集是32位指令集,但是valid architecture只包含64位指令集
解決辦法:valid architecture增加armv7
3. 匯入靜態庫後編譯報錯為
問題起因:
1:可能是靜態庫中不包含這個類。
2:靜態庫工程可能沒有連結到應用。
3:可能是因為靜態庫(.a)為真機版本,不包含模擬器版本(i386)。
解決辦法:1:檢視靜態庫裡面是否存在這個類。
2:Build Phases中沒有新增Link Binary With Libraries 中新增此靜態庫。
3:把除錯目標換成真機 或者 匯入一個模擬器版本跟真機版本合併的版本
同理如果匯入的庫是模擬器版本而用真機除錯也會報錯,所以匯入一個通用的版本是目前來講最好的辦法。
4. 匯入靜態庫後編譯報錯為
問題起因:1:可能原因同上,因為靜態庫不包含報錯的類
2:可能原因同上,因為靜態庫程可能沒有連結到應用。
3:可能是因靜態庫不支援64位
解決辦法:排除前兩個可能原因後,來看第三個起因的解決辦法:檢視靜態庫的提供方是否有更新支援64位,如果最新的靜態庫依然不支援64位的話,則需要獲取其原始碼重新打包靜態庫,valid architecture中新增arm64。
詳細的解決辦法參考stackoverflow。如果不能獲得原始碼的話,鑑於目前蘋果官方需要支援64位,所以只能換別的靜態庫了,否則聯絡開發者進行靜態庫更新。
2:靜態庫工程可能沒有連結到應用。
3:可能是因為靜態庫(.a)為真機版本,不包含模擬器版本(i386)。
解決辦法:1:檢視靜態庫裡面是否存在這個類。
2:Build Phases中沒有新增Link Binary With Libraries 中新增此靜態庫。
3:把除錯目標換成真機 或者 匯入一個模擬器版本跟真機版本合併的版本
同理如果匯入的庫是模擬器版本而用真機除錯也會報錯,所以匯入一個通用的版本是目前來講最好的辦法。
5. 匯入靜態庫後編譯報錯為
問題起因:1:可能原因同上,因為靜態庫不包含報錯的類
2:可能原因同上,因為靜態庫程可能沒有連結到應用。
3:可能是因靜態庫不支援64位
解決辦法:排除前兩個可能原因後,來看第三個起因的解決辦法:檢視靜態庫的提供方是否有更新支援64位,如果最新的靜態庫依然不支援64位的話,則需要獲取其原始碼重新打包靜態庫,valid architecture中新增arm64。
詳細的解決辦法參考stackoverflow。如果不能獲得原始碼的話,鑑於目前蘋果官方需要支援64位,所以只能換別的靜態庫了,否則聯絡開發者進行靜態庫更新。