深入了解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.xml default.properties jni res src 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.xml default.properties jni libs obj res src tests
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.xml jni local.properties proguard-project.txt res tests
build.xml libs 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