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

参考文章:

 

相关文章
相关标签/搜索