ndk代码支持断点调试

背景

android的ndk代码编写一直被认为是很痛苦的一件事情,除了android程序员对c++的陌生外,还有一个主要原因是无法断点调试。无法断点调试很难发现和排查问题,大大影响开发效率。实际上android studio从2.2开始就完全支持ndk开发,并且可以进行断点调试。

实际应用中发现,真正使用新版studio构建c/c++工程的项目极少。这里有个误区是android studio其实是支持ndk-build和cmake两种构建方式的,但是几乎所有的博客在给教程的时候都是用的官方推荐的cmake构建方式。老项目使用ndk-build构建,工程大的mk文件也很复杂,迁移和学习成本都很大。ndk-build和cmake只是编译方式的不同,两者均可以利用lldb进行断点调试,对于其它功能支持也是一样的。

从大的方向上来看,使用cmake构建很美好,cmake作为通用跨平台编译方案,以后肯定有更好的前景。但是对于android本身来说,大家相对都更熟悉ndk-build方案,而如果都能支持相同的功能,显然直接把ndk-build方案迁移过去成本最小。

迁移步骤

下面给出ndk代码的迁移步骤(以下假设你的工程结构是studio工程结构)。build.gradle整体配置如下:

0、首先,在app/src/main/中新建cpp文件夹,将原工程jni中的文件全部复制过来到cpp文件夹中。

1、配置ndk编译参数。注意有些博客提到可以设置arguments参数ndk_application_mk来支持原工程的application.mk配置文件,这个配置在最新版本的android studio实际验证无效。这一步实际上相当于application.mk文件的迁移。cppflags对应的就是application.mk中的app_cppflags配置,abifilters对应的是app_abi配置,其它参数配置则移到arguments中。2、配置android.mk路径。这里是根据build.gradle设置的相对路径3、添加支持的架构。官方工程给的方法是配置productflavors参数

两种配置方法的区别在于,配置defaultconfig中的ndk的abifilters参数,android studio会将所有的架构so打包到一个apk中,但是如果使用productflavors,将会根据不同架构打包不同的apk。google play是支持根据架构下发不同apk到手机上的,但是国内的应用市场不支持。因此如果要在国内上线建议还是使用abifilters参数的方式。4、打开gradle.properties,添加

android.usedeprecatedndk=true

这是因为工程仍然继续使用ndk-build构建方式

官方文档上给了一个选择gradle关联外部cmake和ndk-build的可视化界面的方法。操作是打开project窗格并选择android视图,右键点击您想要关联到原生库的模块(例如 app 模块),并从菜单中选择 link c++ project with gradle。然后就可以看到这样的一个对话框

但是我试着操作了一下,发现没有找到 link c++ project with gradle的选项。不过这个操作最终也是改gradle文件,我们直接修改gradle文件就行。

补充

如果有现有的so想要添加进去,可以在app/src/main中新建jnilibs文件夹,根据架构放入相应的so

使用android studio编译c/c++不会单独生成so,不过可以使用android studio的apk 分析工具查看生成的so。 选择build->analyze apk,从app/build/outputs/apk/目录中选择apk并点击ok。这时候可以在lib//下看到相应的so

断点调试和自动补全

点击run app按钮,android studio会提示你下载缺失的组件,按照操作下载即可。 如果没有配置过ndk地址,需要在local.properties中配置ndk地址。

ndk.dir=/users/zhangpengyu/documents/android/android-ndk-r12

运行后断点,attach到对应进程,等待lldb(android studio用于断点调试的工具)设置完成即可断点到对应工程。

此时我们可以直接在android studio中编辑c++代码,支持自动补全,方法跳转。以及ide所有的其它常见操作,如格式化代码,重构变量名,查看引用等

其它

作为强迫症知道官方推荐用cmake,就是想把项目切换成cmake构建怎么办。我自己试了一下把ffmpeg用cmake编译。其实这部分也有不少文章介绍,但是几乎所有的文章都是链接ffmpeg编译出的动态库。但是实际应用中,我们很少会把ffmpeg编译成动态库再做链接,因为这样安装包过大。我试着使用ffmpeg编译的静态库再使用cmake编译,出现如下错误。有知道如何解决麻烦告诉我

虽然ndk-build编译方案目前官方已经不再推荐,但是大部分时候来说,项目能够快速迁移ndk代码支持断点调试是第一位的。而在长期的历史进程中,我们也相信,google是一家有立场的公司。绝对不会像苹果公司一样,swift语言一个版本是一门语言,并且根本不向下兼容。不尊重开发者,一升级xcode就是不能用。ndk-build构建方式以后可能会不支持,但是那应该也是swift发布10.0版本的时候了。 # 总结 将ndk代码迁移到android studio中,让c++代码支持断点调试,自动补全,能大大提高我们的开发效率。需要在android中用到ndk编程的同学都可以试试。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏奇梦博客

AppNode面板如何隐藏Nginx版本号和自定义默认访问页面 原创 Linux 面板

1154
来自专栏我是业余自学C/C++的

Mac下vim的配置文件

1031
来自专栏FreeBuf

Scrounger:iOS和Android移动应用程序渗透测试框架

Scrounger是一个模块化的移动应用程序渗透测试框架工具。它将Android和iOS这两个主流的移动操作系统同时整合到了一个框架中,极大的方便和满足了我们日...

811
来自专栏difcareer的技术笔记

AndroidStudio阅读Android源码终极篇

几乎在所有的教程里面,都提到说,要阅读Android源码,需要完整编译一次源码,比如我之前的文章使用AndroidStudio阅读Android源码。但是这个完...

862
来自专栏TechBox

[!]The 'pods-xxx' target has libraries with conflicting name: libcrypto.a and libssl.a

1593
来自专栏haifeiWu与他朋友们的专栏

自建脚手架之配置中心--LightConf的实现

常规项目开发过程中, 通常会将配置信息位于在项目resource目录下的properties文件文件中, 配置信息通常包括有: jdbc地址配置、redis地址...

1133
来自专栏十月梦想

通过post向mysql插入数据

        前面简单介绍了php操作mysql的方法,接下来通过post的方式获取的数据插入mysql!

793
来自专栏子勰随笔

Ant中的SVN 使用

1644
来自专栏技术博客

Win7下SQLite的简单使用

  SQLite 是一个软件库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。SQLite 是在世界上最广泛部署的 SQL 数据库引擎。...

592
来自专栏知识分享

inventor应用程序错误---解决方法

---恢复内容开始--- 点击 ? 出现类似 ? 我使用了网上的几个方法,最后是下载了2014--SP1补丁安装后就能正常打开程序了 ? http://pan....

2806

扫码关注云+社区