对于Android NDK编译器ARM和Thumb模式的理解

编译NDK项目时,编译器无法识别arm汇编,设置LOCAL_ARM_MODE := arm后问题解决,

 

NDK文档上对LOCAL_ARM_MODE的说明如下:

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.:

 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:

 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.

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.

 

文档上的说明比较简略,我在网上找了篇不错的文章,如下: 

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

以前在做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指令集)

但是最近在Xcode编译iOS项目时,注意到同为ARM处理器的苹果设备,使用的是Thumb指令集,而且好像还是某种新版本的Thumb指令集,小搜索了一下看到有人说这种armv7引入的叫做Thumb-2的指令集要比arm指令集更好!于是又重新搜索更新了一下大脑知识库…

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(…)后谢了//中文注释,导致编译器处理至此处时直接报了异常,删除注释后就没事了…

参考文章:

 


 

posted on 2015-06-24 11:18  sanlo  阅读(6133)  评论(0编辑  收藏  举报