开发纯ndk程序之环境搭配
- 安装ndk
从安卓官网下载,ndk,双击解压到当前文件夹。建议想装在那个文件夹便解压到那个文件夹,而且文件夹的路径中不要有空格,因为gcc编译的时候会把空格前后两个字符串作为两个文件夹来对待。
- 使用gcc手动编译
使用gcc编译程序需要先编写makefile文件,然后通过gcc make工具进行编译,makefile文件内容如下:
NDK_ROOT=C:/android-ndk-r10d
TOOLCHAINS_ROOT=$(NDK_ROOT)/toolchains/arm-linux-androideabi-4.9/prebuilt/windows
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/4.9/include-fixed
PLATFORM_ROOT=$(NDK_ROOT)/platforms/android-21/arch-arm
PLATFORM_INCLUDE=$(PLATFORM_ROOT)/usr/include
PLATFORM_LIB=$(PLATFORM_ROOT)/usr/lib
MODULE_NAME=hello
RM=del
FLAGS=-I$(TOOLCHAINS_INCLUDE)\
-I$(PLATFORM_INCLUDE)\
-L$(PLATFORM_LIB)\
-nostdlib\
-lgcc\
-Bdynamic\
-lc
OBJS=$(MODULE_NAME).o\
$(PLATFORM_LIB)/crtbegin_dynamic.o\
$(PLATFORM_LIB)/crtend_android.o all:
$(TOOLCHAINS_PREFIX)-gcc $(FLAGS) -c $(MODULE_NAME).c -o $(MODULE_NAME).o
$(TOOLCHAINS_PREFIX)-gcc $(FLAGS) $(OBJS) -o $(MODULE_NAME)
clean:
$(RM) *.o
install:
adb push $(MODULE_NAME) /data/local/tmp
adb shell chmod 755 /data/local/tmp/$(MODULE_NAME)
其中gcc make工具位于..\android-ndk-r10d\prebuilt\windows\bin下,此目录需要加入到系统或临时的PATH环境变量中,然后将hello.c于makefile文件放到一个目录中,开启虚拟机,然后依次执行以下命令:
make
make install
adb shell /data/local/tmp/hello
便会看到熟悉的“hello world!!!”输出了。
makefile中的I和L要记得分清,我没注意到,结果编译的时候总是报错。
- 使用ndk-build编译
使用ndk-build编译需要一个Android工程,这里使用android脚本来生成一个android工程,此脚本位于../sdk/tools下面,文件名是android.bat,在命令行输入“android --help”可以查看完整的命令,如“android avd”可以启动安卓虚拟机,这里使用“create project”选项,如下面:
android create project -n hello -p hello -t android- -k com.droider.hello -a MyActivity
“-n”指定android工程的名称,“-t”指定生成android工程所需要使用平台版本号,此版本号使用“android list”列出,“-p”指定生成工程的目录名,“-k”指定android工程的包名,“-a”指定默认Activity的名称。
Android工程生成好了,在工程目录下面新建一个jni文件夹,并将hello.c文件复制进去,然后编写ndk-build所需要的两个脚本,名字分别为Android.mk与Application.mk,其中后者是可选的。首先,这两个文件的内容在NDK文档中都有描述,打开android-ndk-r10d\docs里面Start_Here.html,选择“NDK Programmer's Guide”,在左侧列表中有“Android.mk“与”Application.mk”按钮,里面有详细内容描述。
好,首先编写Android.mk,如下
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS)
LOCAL_ARM_MODULE := arm LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c include $(BUILD_EXECUTABLE)
LOCAL_PATH 定义了本地源码的路径,它是Android.mk中必须首先定义好的变量,call my-dir指定了调用my-dir宏,它是由编译系统提供的,返回Android.mk文件本身所在的路径,一般与源码文件目录相同。
CLEAR_VARS指定让编译系统清除掉一些已经定义过的宏,这些宏的定义都是全局的。如LOCAL_MODULE、LOCAL_SRC_FILE,当一个GUN MAKE在编译多个模块时,必须清除并重新设置它们。
LOCAL_ARM_MODULE 指定生成的原生程序所使用的ARM指令模式。arm表示使用32指令系统。
LOCAL_MODULE 指定模块的名称。
LOCAL_SRC_FILE指定c或c++源文件列表。
include $(BUILD_EXECUTABLE)指定生成的文件类型。
然后是Application.mk,如下
APP_ABI := armeabi-v7a
这里指定平台是armeabi-v7a。
最后将Android.mk与Application.mk共同放在jni文件夹下,在工程目录下执行ndk-build,最后生成的文件在libs文件夹下。
- 搭配调试环境
首先,调试需要gdbserver,还需要有调试符号信息,这里有两个方案,我看文档上说事两个方案缺一不可,但是我测试是两个方案中一个就可以了,其一便是在使用“ndk-build NDK_DEBUG=1”命令来编译,另一个便是在AndroidManifest.xml文件中的application节添加“android:debuggable="true"”属性,编译后结果如下
[armeabi-v7a] Gdbserver : [arm-linux-androideabi-4.8] libs/armeabi-v7a/gdbserver
[armeabi-v7a] Gdbsetup : libs/armeabi-v7a/gdb.setup
[armeabi-v7a] Install : hello => libs/armeabi-v7a/hello
可见生成了gdbserver,在libs文件夹里面,而含有调试符号信息的hello则在objs文件夹里面,然后将这两个文件一起推送到安卓设备里面,使用如下命令:
adb push ./obj/local/armeabi-v7a/hello /data/local/tmp
adb push ./libs/armeabi-v7a/gdbserver /data/local/tmp
adb shell chmod /data/local/tmp/hello
adb shell chmod /data/local/tmp/gdbserver
启动gdbserver,使其监听端口7000,如下:
adb shell /data/local/tmp/gdbserver : /data/local/tmp/hello
结果如下
adb shell /data/local/tmp/gdbserver : /data/local/tmp/hello
Process /data/local/tmp/hello created; pid =
Listening on port
然后启动另一个终端,gdb在android-ndk-r10d\toolchains\arm-linux-androideabi-4.9\prebuilt\windows\bin文件夹里面,我是见这个文件夹路径添加到了环境变量,然后将arm-linux-androideabi-gdb.exe名字改为gdb.exe,这样可以少敲几个字,后来我做成了makefile文件,发现其实做了无用功,呵呵。首先将安卓设备的7000端口映射到本地7000端口,使用如下命令
adb forward tcp: tcp:
然后,启动gdb,同时别忘了指定调试文件啊,不然会找不到调试符号的,命令如下
gdb ./obj/local/armeabi-v7a/hello
此时,进入了gdb,如下
GNU gdb (GDB) 7.6
Copyright (C) Free Software Foundation, Inc.
License GPLv3+: GNU GPL version or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=i586-pc-mingw32msvc --target=arm-linux-android".
For bug reporting instructions, please see:
<http://source.android.com/source/report-bugs.html>...
Reading symbols from F:\work\Code\ndk\NdkBuild\helbul\obj\local\armeabi-v7a\hello...done.
(gdb)
然后为gdb指定调试进程,如下
target remote localhost:
此时,可以调试程序了,先来感受一下吧,使用l命令查看一下源码:
(gdb) l
Cannot access memory at address 0x0
#include<stdio.h>
int main(int argc, void* argv)
{
printf("hello world\n");
return ;
}(gdb)
然后就是gdb调试的内容了。
我在调试的时候总是提醒找不到共享库,此库位于android-ndk-r10d\platforms\android-21\arch-arm\usr\lib里面,可以使用下面的命令来设置:
set solib-search-path C:/android-ndk-r10d/platforms/android-/arch-arm/usr/lib
由于指定远程调试进程和设置共享库位置经常用到,可以写成gdb脚本,如下:
define ig
target remote localhost:
set solib-search-path C:/android-ndk-r10d/platforms/android-/arch-arm/usr/lib
end
然后保存为文件,文件名我取为“InitGdb.gdb”,然后启动gdb后,使用source命令载入脚本,并运行,如下:
(gdb) source InitGdb.gdb
(gdb) ig
果然还是讨厌重复性的劳动。
虽然设置了共享库的目录,但还是提醒我库的位置不对,不匹配,所以我想把他们都编译成静态库,结果老失败,这里留下个悬念,以后再来解决吧。
参考:
《Android软件安全与逆向分析》 -- 丰生强
开发纯ndk程序之环境搭配的更多相关文章
- Android 第一个程序 及 环境搭配
一. JDK配置 1.找到jdk安装路径 2.配置环境变量(建议配置在系统变量里面) 1).配置JAVA_HOME变量 2).配置 CLASSPATH 环境变量 CLASSPATH=.;%JAVA_H ...
- 在VS2010下开发C语言程序
妈蛋,我发现VS下开发C语言,并不是把文件名改成.C的就行了.VS2010不支持C99. 也就是函数局部变量声明必须放在函数的开头.难怪,我从Linux下移植过来的.c工程怎么是编译错误呢,发现是变 ...
- 史上最易懂的Android jni开发资料--NDK环境搭建
谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK提供 ...
- Android jni开发资料--NDK环境搭建
谷歌改良了ndk的开发流程,对于Windows环境下NDK的开发,如果使用的NDK是r7之前的版本,必须要安装Cygwin才能使用NDK.而在NDKr7开始,Google的Windows版的NDK ...
- 在桌面Linux环境下开发图形界面程序的方案对比
在Linux下开发GUI程序的方法有很多,比如Gnome桌面使用GTK+作为默认的图形界面库,KDE桌面使用Qt作为默认的图形界面库,wxWidgets则是另一个使用广泛的图形库,此外使用Java中的 ...
- 【转载】Ubuntu Android开发环境搭配
Ubuntu Android开发环境搭配 安装Ubuntu Android应用程序开发环境需要如下几个软件 Java开发包:JDK 1.5/1.6 开发集成环境(IDE): Eclipse 3 ...
- Windows2008+MyEclipse10+Android开发环境搭配
Windows2008+MyEclipse10+Android开发环境搭配 知识要点:64位系统中离线安装MyEclipse的ADT插件步骤办法 功能描述:解决Windows2008+MyEclips ...
- ok6410[002] ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境
ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境 系统: ubuntu16.04 裸板: 飞凌公司OK6410开发板 目标:搭建基于ubuntu1604系统和基于RA ...
- Python3的桌面程序开发利器:Eric6的环境搭建、使用
本文旨在通过一个简单的demo,介绍基于Python3.PyQT5的环境下开发桌面应用程序的一种方案,当然开发Python的桌面应用程序不止是PyQT 这一种方案,还可以使用Python自带的Tkin ...
随机推荐
- .sdp文件格式介绍
最近做RTSP流播放,需要了解.sdp这种会话描述的文件格式,当然,里面的具体语法有SDP解析器来分析.但是我需要大概了解一些字段的意思,它是文本描述的,采用key value的形式描述. https ...
- android实现类似于支付宝余额快速闪动的效果
效果如下: 此图片不会动,但实际上是会快速跳动的. 之前看到有支付宝的效果非常牛逼.就是进去看到余额呼噜噜的直接上蹿下跳到具体数字,效果帅,但不知道怎么实现,最近终于知道了. 思路: 首先经常用 ...
- 如何在Windows下使用matplotlib
在开始之前,向matplotlib的创造者,John D. Hunter表示崇高的敬意,和无尽的怀念. (John D. Hunter 1968-2012) matplotlib是一个给予Python ...
- win7配置简单的FTP服务器
1.开启一些win7默认是关闭状态的功能 步骤:控制面板 -> 程序和功能 -> 打开或关闭Windows功能,然后勾选下图中圈起来的部分: 2.添加FTP站点 步骤:桌面的计算机图标 - ...
- 菜单栏始终浮动在顶部 js
//菜单栏始终浮动在顶部var navH = $(".trade-tab-bot").offset().top;//获取要定位元素距离浏览器顶部的距离//滚动条事件$(window ...
- 【iOS基础】iOS 线程相关技术
零.线程的注意点(掌握)1.不要同时开太多的线程(1~3条线程即可,不要超过5条)2.线程概念1> 主线程 : UI线程,显示.刷新UI界面,处理UI控件的事件2> 子线程 : 后台线程, ...
- Codeforces 385C Bear and Prime Numbers
题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...
- java.lang.OutOfMemoryError: Java heap space错误及处理办法(收集整理、转)
下面是从网上找到的关于堆空间溢出的错误解决的方法: java.lang.OutOfMemoryError: Java heap space ============================== ...
- mybatis简单应用(基于配置文件)
本文主要介绍了如何使用mybatis进行简单的数据库操作.本人使用的是mybatis3.05. 1.创建数据库表(User表) CREATETABLE `NewTable` (`userId` big ...
- Java基础知识强化32:String类之String类的判断功能
1. String类的判断功能: boolean equals (Object obj ) boolean equalsIgnoreCase (String str ) boolean contain ...