android NDK开发、编译、调试环境搭建与操作入门
前话
现在越来越多的应用开发、场景会用到NDK,NDK的开发环境和工具也可谓是“日新月异”,Googleg还是比较给力,时至今日ADT已经发布了21.0.1,实际上从20.0.3已经对我们需要使用的NDK有了比较好的支持了,使用Eclipse可以直接断点NDK代码。
以前似乎我们只能通过打日志或者在其它工具如VS、Xcode下写测试工程来调试,以及使用神话般的GDB来调试,搭建调试环境算是程序调试过程中一点点雕虫小技吧。不废话,直入主题。
一、 首先工具准备
Eclipse ADT插件,版本要求20.0.3以上;NDK,现在最新版本是r8d。Android官网上提供了eclipse、SDK、ADT打包下载,而Android开发不是必须的NDK需要单独下载。不过还是很多人不喜欢打包形式的,对自己喜欢的eclipse版本非常钟情之类。我们按非打包的形式下载的情况来搭建NDK环境:下载好之后,解压eclipse,安装ADT插件,以前我们用eclipse开发C/C++需要安装CDT插件,现在ADT插件已经包含了CDT,安装完ADT,需要设置下SDK目录,然后通过SDK Manager更新下SDK,然后还需要设置NDK目录。当然还有cygwin,官方下载默认安装选项就OK,设置好PATH就不用管了!
二、 几项简单设置
SDK目录配置:
Eclipse文件菜单选择“Window”--->“Preferences”--->“Android”--->设置“SDK Location”--->”Browse”选择SDK目录即可。 如下图:
到此,普通Android开发环境已经OK,如果需要开发NDK,那么继续。 NDK目录配置: 设置完SDK后还需在“Android”配置项上设置下“NDK”,选择NDK后,有一个选项“NDK Location”,这里配置NDK根目录。
如下图:
接下来选择在你要开发NDK的Android项目上右键,选择“Android Tools”再添加Native的支持。
如果不需要调试,这时编译环境已经OK了; 另外:如果需要兼容老的项目,那么老项目的路径得规划好了,新项目我个人觉得把源码都通过eclipse来添加和编辑也未尝不可。这里就不细说这些具体的开发细节了,只探讨环境问题。 除了能开发、编译NDK之外,如果需要调试NDK,那么继续:
修改编译命令,在C++ Build中设置Build command,把Use default选项去掉,在ndk-build后面添加参数NDK_DEBUG=1,使得编译出的SO带源码等调试信息。 如下图:
开发、编译、调试环境到这里算是OK了。调试具体的操作继续看下面。
三、 操作方法
编译后如果查看源代码:
Eclipse编译后,我们可以在C/C++视图中的Project窗口看到一个Binaries条目,里面有我们的so,调试环境中编译出来的so和非调试环境编译出来的so不一样,点它左边的个小三解,就可以看到源码了,这对于很多不是在此项目中开发的源码,这个查看方法非常有效。另外我们也可以在Debug视图中打开Executables的窗口,这里除了可以看到你自己项目的so,还可以添加外面编译好的带调试信息的so,然后在右边就也可以看到源码了。
具体见如下两个截图:
Executables窗口
最最最基本的操作——打断点:
打开源码后,打断点就跟平常一样的了,不过有时候可能会双击打断点,点半天也点不上,不急,这种情况下,你可以先启动Native Debug,
让eclipse先领会下你的意思,具体操作如下截图:
启动Native Debug
添加断点,跟平常Java断点没有太多区别:
断点进来后的效果:
跑起来之后,执行操作就等着进到断点这里来吧,效果如下,看图就什么都了解,变量、调用堆栈、反汇编、内存监控,基本上已经够我们用了,当然这比起原生的GDB,还是有些差异的,不能使用break commands,不能打补丁,不过我们也可以知足了。到这里你可以开始你的捉虫、抓鬼活动了。
四、 可能遇到的问题以及解决办法
笔者在使用这个环境中还遇到了一些问题,也分享下,如果遇到同样的问题,大家也可以少走弯路了,再看下面吧。
1、 Eclipse可能报一堆的错误提示 由于eclipse的语法检查,当你打开一个源码,尤其是引入外面开发完成的项目,因为源码不是在工程中管理的,大部分情况会报一堆的错误提示,而你是明确这些问题实际上是不存在的,那么就可以这样子做了,设置项目属性,把eclipse多管的这些闲事给免了它的职,如下图,保存后,你会发现你的problems窗口下非常清爽了:
2、 NDK编译时报错 NDK编译时很多时候可能还会有各种各样的错误,我的解决办法就是google,我们遇到过的问题,一定别人早就遇到过了,一般就是在mk中加入一些参数即可,比如下面我就遇到过的一个问题 Android NDK: WARNING: APP_PLATFORM android-X is larger than android:minSdkVersion x in ./AndroidManifest.xm……
这个问题的解决办法在 Application.mk中添加一个参数APP_PLATFORM :=android-<minSdkVersion>就万事大吉了。
3、 NDK调试目标库(so)时,编译过程会清除libs目录所有的so 解决办法,○1把其它的so拷出libs目录,采用指定路径方式来加载so, ○2把其它so拷到另外一个目录,然后在mk文件中添加一个编译target,对这些so 进行一次拷贝,当默的“all”执行完之后再执行这个target,对其它so进行一次拷贝,当然也可以使用Ant添加一个编译脚本来做你想要做的事情。 在Android.mk中添加一个make的target,因为我Windows下装了cygwin所以用了cp来拷贝,Windows下相应的改成copy吧
然后在增量编译命令中加入这些target,如下图
4、 编译慢 这个问题真的是程序员必定会遇到的问题,不过在这里如是你是跟我一样是在Windows下进行NDK开发,蛋痛的很,编译时间你完全可以去喝杯咖啡。一个小改进,我们在配置编译命令的时候,加一个参数“-j4”,开启多线程去编,不过这时候你就真的只有去喝咖啡了,电脑CPU已经满了,还有一个解决办法,如果你面子大的话,找BOSS申请好机器、加内存换SSD去。
5、 一些不需要打断点这么麻烦的问题 很多情况下我们都只是打了日志就够了,NDK也提供了一些工具像ndk-stack, addr2line之类的可以帮助我们来分析日志、出错代码行等。
6、NDK调试,经常会碰错误:
No symbol table is loaded. Use the "file" command.
public static void test1(){ Log.i(tag, "test1"); }然后在主activity起来的时候,调用一下这个方法就OK了。
我所遇到的这些问题还是比较少,肯定还有更多更有趣更难搞的问题,欢迎大家找笔者一起交流遇到的问题。
编辑这么一笔文章真的好不容易啊,累了半天。还好之前在公司内部发贴的时候已经写好并且编辑过一次了,真心佩服那些牛人,写那么多文章,真心觉得不容易。转的一定要标明原文链接啊。
android职业交流QQ 群,有兴趣的可以一起来多搞搞技术、职业交流,互相学习、提高,互通好的职业信息,群号:66262654