深入了解android NDK
2.1 Android 提供的组件:
ARM,x86和MIPS交驻编译器
构建系统
Java原生接口头文件
C库
Math库
POSIX线程
最小的c++库
ZLIB压缩库
动态链接库
Android日志库
Android像素缓冲库
Android 原生应用apis
OpenGL ES 3D 图形库
openSL ES 原生音频库
openMAX AL最小支持
2.2 android NDK的目录结构
名称 | 介绍 |
Ndk-build | Shell角本,构建系统的起始点 |
Ndk-gdb | Shell角本,GNU调试器原生组件 |
Ndk-stack | Shell角本,用于分析原生组件崩溃时的堆栈追踪 |
build | 目录,包含了构建系统的所有模块 |
platforms | 目录,支持不同android目标版本的头文件和库文件 |
simple | 示例应用 |
source | 可导入的共享模块 |
toolchains | 不同版本的交叉编译器 |
2.3 简单的示例程序
配置eclipse,windows-àpreference-àandroid-àNDK,指定ndk的目录
导入ndk自带示例程序
向项目中添加原生支持右击项目àandroidTools-àadd Native Support,指定共享库名
运行项目
可以在控制台看到构建信息
13:08:35 **** Incremental Build ofconfiguration Default for project HelloJni ****
"D:\\tools\\android-ndk-r9b\\ndk-build.cmd"all
[armeabi] Gdbserver : [arm-linux-androideabi-4.6]libs/armeabi/gdbserver
[armeabi] Gdbsetup : libs/armeabi/gdb.setup
[armeabi] Install : libhello-jni.so =>libs/armeabi/libhello-jni.so
13:08:36 Build Finished (took 388ms)
用命令行对项目进行构建
A 构建原生组件
D:\workspace4>cdhello-jni
D:\workspace4\hello-jni>ls
AndroidManifest.xmldefault.properties jni ressrc tests
D:\workspace4\hello-jni>ndk-build
[armeabi] Gdbserver :[arm-linux-androideabi-4.6] libs/armeabi/gdbserver
[armeabi] Gdbsetup :libs/armeabi/gdb.setup
[armeabi] Compile thumb :hello-jni <= hello-jni.c
[armeabi] SharedLibrary :libhello-jni.so
[armeabi] Install :libhello-jni.so => libs/armeabi/libhello-jni.so
D:\workspace4\hello-jni>ls
AndroidManifest.xmldefault.properties jni libsobj res srctests
B 构建java应用程序,并将其与原生组件打包
生成apach ANT构建文件
D:\workspace4\hello-jni>android update project -p . -nhello-jni -t android-14 -
-subprojects
Updated and renamed default.properties to project.properties
Updated local.properties
Added file D:\workspace4\hello-jni\build.xml
Added file D:\workspace4\hello-jni\proguard-project.txt
Updated and renamed default.properties to project.properties
Updated local.properties
Added file D:\workspace4\hello-jni\tests\build.xml
Added file D:\workspace4\hello-jni\tests\proguard-project.txt
D:\workspace4\hello-jni>ls
AndroidManifest.xmljni local.properties proguard-project.txt restests
build.xmllibs obj project.properties src
执行ant debug构建并生成apk包
在项目的目录结构中
jni | 原生组件源代码,描述原生组件方法的android.mk |
libs | 构建过程中创建该目录 |
obj | 编译源代码后产生的目标文件都放在该目录 |
2.4 构建环境
构建系统的片段位于build/core子目录中
Android.mk位于jni子目录中
示例代码如下
LOCAL_PATH := $(callmy-dir) //定位源文件,my-dir是一个宏
include $(CLEAR_VARS) //clear_vars.mk 擦除local_path以外的local_*
LOCAL_MODULE := hello-jni //定义模块名称 生成libhello-jni.so
LOCAL_SRC_FILES :=hello-jni.c //源文件列表
include$(BUILD_SHARED_LIBRARY) //成生共享库
@@@@@@构建多个共享库,示例代码如下:@@@@@@@@@@
LOCAL_PATH := $(call my-dir)
#模块一
include $(CLEAR_VARS)
LOCAL_MODULE := modul1
LOCAL_SRC_FILES := modul1.c
include $(BUILD_SHARED_LIBRARY)
#模块二
include $(CLEAR_VARS)
LOCAL_MODULE := modul2
LOCAL_SRC_FILES := modul2.c
include $(BUILD_SHARED_LIBRARY)
@@@@@@@@构建静态库(使用第三方源代码)@@@@@@@@@
LOCAL_PATH=$(cal l my-dir)
#第三方avi库
Include $(CLEAR_VARS)
LOCAL_MODULE :=avilib
LOCAL_SRC_FILES :=avilib.c,platform_posix.c
Include $(BUILD_STATIC_LIBRARY)
#原生模块
include $(CLEAR_VARS)
LOCAL_MODULE := modul
LOCAL_SRC_FILES := modul.c
LOCAL_STATIC_LIBRARIES :=avilib //定义变量,使用该模块
include $(BUILD_SHARED_LIBRARY)
@@@@@用共享库,共享通用模块(即多个模块使用同一第一方源代码)@@@@@@@
LOCAL_PATH=$(cal l my-dir)
#第三方avi库
Include $(CLEAR_VARS)
LOCAL_MODULE :=avilib
LOCAL_SRC_FILES :=avilib.c,platform_posix.c
Include $(BUILD_SHARED_LIBRARY)
#原生模块一
include $(CLEAR_VARS)
LOCAL_MODULE := modul1
LOCAL_SRC_FILES := modul1.c
LOCAL_SHARED_LIBRARIES :=avilib//
include $(BUILD_SHARED_LIBRARY)
#原生模块二
include $(CLEAR_VARS)
LOCAL_MODULE := modul2
LOCAL_SRC_FILES := modu2l.c
LOCAL_SHARED_LIBRARIES :=avilib //
include $(BUILD_SHARED_LIBRARY)
@@@@@@@@@@@@@在多个NDK项目中共享模块@@@@@@@@@@@@@@
#原生模块
include $(CLEAR_VARS)
LOCAL_MODULE := modul
LOCAL_SRC_FILES := modul.c
LOCAL_STATIC_LIBRARIES :=avilib
include $(BUILD_SHARED_LIBRARY)
$calll (import_module,**/***) //指定路径名,可以在一环境变量中定义一个共享模块路径(所以***/***可以是一个相对路径)
@@@@@@@@@@@使用prebuilt库@@@@@@@@@@@@@@@@
应用场景: A 在不发布源代码的情况下将你的模块发布给他人
B 想使用共享模块的预见版来加速构建过程
注:prebuilt库中不包含机器体系结构的信息
示例代码如下:
#第三方avi库
Include $(CLEAR_VARS)
LOCAL_MODULE :=avilib
LOCAL_SRC_FILES :=libavilib.so//需要将该库复制到libs目录下
Include $(PREBUILT_STATIC_LIBRARY)
#原生模块一
include $(CLEAR_VARS)
LOCAL_MODULE := modul
LOCAL_SRC_FILES := modul.c
LOCAL_SHARED_LIBRARIES :=avilib //
include $(BUILD_SHARED_LIBRARY)
@@@@@@@@@@@@构建独立的可执行文件@@@@@@@@@@@@@@@@@@
…
include $(BUILD_EXECUTABLE)
…
会生成android设备上的常规linux应用程序,可以直接执行
@@@@@@@@@@@@其他构建系统变量@@@@@@@@@@@@@@@@@@@
变量名 | 用途 |
TARGET_ARCH | 目标CPU体系名称 |
TARGET_PLATFORM | Android平台的名称 |
TARGET_ARCH_ABI | 目标CPU体系名称和ABI的名称 |
LOCAL_MODULE_FILENAME | 重新定义生成输出文件的名称 |
LOCAL_CPP_EXTENSION | 可以为c++源文件提供一个或多个扩展名 |
LOCAL_CPP_FEATURES | 模块所依赖的c++的特性 |
LOCAL_C_INCLUDES | NDK安装目录的相对路径,用来搜索头文件 |
LOCAL_CFLAGS | 编译器标志 |
LOCAL_CPPFLAGS | 编译器标志 |
LOCAL_LDLIBS | 目标文件进行链接时所需标志 |
LOCAL_ALLOW_UNDEFINED _SYMBOLS | 禁止在生成文件中进行缺失符检查 |
LOCAL_ARM_MODE | 生成ARM二进制类型 |
LOCAL_ARM_NEON | 指定高给单指令流和多数据流内联函数 |
LOCAL_DISABLE_NO_EXECUTE | 禁用nx bit安全特性 |
LOCAL_EXPORT_CFLAGS | 编译标志 |
LOCAL_EXPORT_CPPFLAGS | 编译标志 |
LOCAL_EXPORT_LDFLAGS | 链接器标志 |
LOCAL_EXPORT_C_INCLUDES | 允许记录路径集 |
LOCAL_SHORT_COMMANDS | 对于有大量资源/独立静态库/共享库,应设为true |
LOCAL_FLITER_ASM | 过虑来自 local_src_files变量的装配文件 |
@@@@@@@@@@@@@其他的构建系统宏函数@@@@@@@@@@@@@@@@@
All_subdir_makefiles | 返回当前目录下的所有子目录下的android.mk构建文件列表 |
This_makefile | 返回当前android.mk的路径 |
Parent_makefile | 父android.mk路径 |
Grand_parent_makefile | 祖父目录 |
@@@@@@@@@@@@@@@@定义新变量@@@@@@@@@@@@@@@@@@
变量名:=值
使用时: $(变量名)
@@@@@@@@@@@@@@条件操作@@@@@@@@@@@@@@@@@@@@@@@
Ifeq
…
Else
…
Endif
Application.mk
是一个可选构建文件,应用程序需要哪些模块
APP_MODULES | 声明所有模块 |
APP_OPTIM | Release/debug改变生成二进制文件的优先级 |
APP_CFLAGS | 编 译器标志 |
APP_CPPFLAGS | 编译器标志 |
APP_BUILD_SCRIPT | 在不同目录(非jni目录)下查找构建文件 |
APP_ABI | 构建系统为armeabi ABI生成二进制文件 |
APP_STL | 使用最小的STL运行库 |
APP_GNUSTL_FORCE _CPP_FEATURES | 依赖c++特性 |
APP_SHORT_COMMANDS | 可以在项目中使用更短的命令 |
2.5 使用NDK-Build角本
Ndk-build参数名称 项目名称
参数:
-C 指定项目路径
-B 重新构建目标
-j 指定并行执行数量(GNU make可以并行执行构建命令)
2.6 排除构建系统故障
开启日志 ndk-build NDK_LOG=1
只显示构建命令ndk-build V=1