對於Android NDK編譯器ARM和Thumb模式的理解

編譯NDK項目時,編譯器沒法識別arm彙編,設置LOCAL_ARM_MODE := arm後問題解決,html

 

NDK文檔上對LOCAL_ARM_MODE的說明以下:web

LOCAL_ARM_MODE

By default, ARM target binaries are generated in 'thumb' mode, where each instruction are 16-bit wide, and linked with /thumb STL libraries. You can define this variable to 'arm' if you want to force the generation of the module's object files in 'arm' (32-bit instructions) mode. E.g.:xcode

 LOCAL_ARM_MODE := arm 

Note that you can also instruct the build system to only build specific sources in ARM mode by appending an '.arm' suffix to its source file name. For example, with:app

 LOCAL_SRC_FILES := foo.c bar.c.arm 

Tells the build system to always compile 'bar.c' in ARM mode, and to build foo.c according to the value of LOCAL_ARM_MODE.ide

NOTE: Setting APP_OPTIM to 'debug' in your Application.mk will also force the generation of ARM binaries as well. This is due to bugs in the toolchain debugger that don't deal too well with thumb code.post

 

文檔上的說明比較簡略,我在網上找了篇不錯的文章,以下: ui

原文連接:http://blog.k-res.net/archives/1291.html this

之前在作Symbian的時候,曾經研究過ARM CPU的指令集問題,ARM處理器支持兩套指令集,即ARM和Thumb。ARM爲32位指令集而Thumb爲16位指令集,理論上32位能夠提供更快的執行速度但會生成更大的二進制執行文件,而16位的Thumb則偏偏相反,省地但慢,這也正是體現出了ARM對於嵌入式設備的專業性。對於我這種犧牲一切換速度的理念來講,當時就留下了ARM就比Thumb快的印象,以至於如今在作Android NDK原生開發時,也是優先用ARM指令集。(這個能夠經過在Android.mk中加入LOCAL_ARM_MODE := arm控制,默認狀況下NDK使用Thumb指令集)url

可是最近在Xcode編譯iOS項目時,注意到同爲ARM處理器的蘋果設備,使用的是Thumb指令集,並且好像仍是某種新版本的Thumb指令集,小搜索了一下看到有人說這種armv7引入的叫作Thumb-2的指令集要比arm指令集更好!因而又從新搜索更新了一下大腦知識庫…spa

armv7對於蘋果設備來講,意味着iPhone 3GS以上級別的設備的CPU,而目前主流的Android設備幾乎全是armv7處理器的了。也許對於早起的armv6處理器來講,ARM指令集還有優點,可是對於新的v7處理器,各類資料都代表Thumb-2要更好一些。

總的來講,ARM指令集會在某些方面有優點,好比手寫彙編(額…),而Thumb則能生成更精簡的代碼,並且還有一點我以前沒有太意識到的問題就是:省電!因此仔細斟酌後,我仍是決定把NDK編譯選項由原來的ARM改回默認的Thumb,遵循默認原則吧仍是。

而對於v7和非v7的問題,Android上能夠這樣處理,以略增大apk爲代價,加入單獨針對v7和非v7版的so文件,這樣apk在安裝時會自動根據目標設備的CPU安裝合適的so庫,從而達到更好的效果,具體作法是在Application.mk中加入」APP_ABI := armeabi armeabi-v7a"

另外,隨着項目規模的增大,代碼編譯生成時間會大大增長,這時候能夠考慮更換r8c版NDK新加入的Clang編譯器(蘋果家的編譯器,新版Xcode默認就用它),實測發現Clang比GCC明顯快不少,並且對於warning, error的顯示也比GCC要人性的多(有人說GCC的提示就像是天書,呵呵),不過聽說Clang也有一些不足,好比對於標準的支持不如GCC(這話怎麼聽着像是說MS的…),不如GCC支持的語言廣等,但感受對於Android原生開發來講都是些可有可無的事,我只要編譯快,運行快就行了!

改用Clang編譯器的方法以下:

對於ndk-build方式,可使用「export NDK_TOOLCHAIN_VERSION=clang3.1」導出環境變量,或者將這個環境變量設置加入到Application.mk中。

對於獨立編譯方式,在make-standalone-toolchain.sh腳本中加入–llvm-version=3.1 並在makefile中用<tool-path>/bin/clang and <tool-path>/bin/clang++替換 CC 和CXX 參數。

PS:實際編譯時發現Clang好像對中文註釋支持不是特別好,好比有端代碼在if(…)後謝了//中文註釋,致使編譯器處理至此處時直接報了異常,刪除註釋後就沒事了…

參考文章:

 

相關文章
相關標籤/搜索