LOCAL_PATH:= $(call my-dir) #位于最开始,用来为定位源文件的位置$(call my-dir)的作用就是返回当前目录的路径。
include $(CLEAR_VARS) #清除一些变量的值,但是LOCAL_PATH除外。
LOCAL_MODULE := fp_identify #用来指定当前待编译模块的名称。
LOCAL_SRC_FILES := libfp_identify.so #第三方库
include $(PREBUILT_SHARED_LIBRARY) #表示引用第三方库
include $(CLEAR_VARS)
LOCAL_SRC_FILES := com_FingerMechine_FingerMechine.c #用来指定参与编译的源代码文件
LDFLAGS = -llog -shared #加上Log功能
#LOCAL_CFLAGS := -DANDROID
#LOCAL_CFLAGS += -Wno-sequence-point -Wno-extra
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include #指定头文件的路径
LOCAL_MODULE:= fp_jni_module
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog #引用外部库文件,-L指定该lib文件的存放路径
#LOCAL_SHARED_LIBRARIES:=liblog libcutils
LOCAL_SHARED_LIBRARIES := libfp_identify #在顶层.mk中写入引入的第三方库
include $(BUILD_SHARED_LIBRARY) #编译生成动态库
include $(CLEAR_VARS)
LOCAL_SRC_FILES := com_LEDController_Gpio.c
LDFLAGS = -llog -shared
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
LOCAL_MODULE:= gpio_jni_module
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog #表示告诉链接器生成的模块要在加载时刻链接到/system/usr/lib/liblog.so
include $(BUILD_SHARED_LIBRARY) #用来指示将当前模块编译为共享库,加前缀lib,后缀.so
2、定义多个Android.mk文件。
有的时候,需要编译的模块比较多,我们可能会将对应的模块放置在相应的目录中,这样,我们可以在每个目录中定义对应的Android.mk文件(类似于上面的写法),最后,在根目录放置一个Android.mk文件,内容如下:
include $(call all-subdir-makefiles)
只需要这一行就可以了,它的作用就是包含所有子目录中的Android.mk文件
3、也可以在一个Android.mk文件里包含多个模块。
很直观的想法就是将第一个Android.mk文件的内容复制一份,然后修改。我最开始也是这样做的,但是后来出现问题了,在第二个模块中的源码找不到,最后还是看文档,发现里面已经有示例解释了:
LOCAL_PATH := $(call my-dir)
the path of the *last* *included* *Makefile* during the parsing of
build scripts. Do not call my-dir after including another file.
大意是:基于GNU make的工作方式,$(call my-dir)会返回在解析build脚本时,遇到的最后一个 include中涉及的目录。
所以,很多时候,在这个Android.mk里面只需要调用一次$(call my-dir)就够了,如果所有的源文件都在一个目录中。
如果需要的话,可以在第一次调用call my-dir的时候,将值保存下来,比如:
MY_LOCAL_PATH := $(call my-dir)
LOCAL_PATH := $(MY_LOCAL_PATH)
LOCAL_PATH := $(MY_LOCAL_PATH)
4)如何在Android NDK中调用第三方库文件(.so)
1.在project/jni目录下创建prebuilt子目录(目录名可自定义).
2.将第三方.so放到prebuilt中,并创建Android.mk, 内容如下:
LOCAL_PATH := $(call my-dir)3.在project/jni/Android.mk中加入include $(CLEAR_VARS)
LOCAL_MODULE := xxx
LOCAL_SRC_FILES := libxxx.so
include $(PREBUILT_SHARED_LIBRARY)
4.在project/jni/android.mk的最后加入
5.运行cygwin, 到project目录下, 运行$NDK/ndk-build
可以参考这篇文章,比较详细:Android.mk详解
在Android中已经为我们程序员提供了一些动态库,如Log,怎么把它们加载到我们的程序中呢?
找到了这篇文章,可以看一下:使用 Android NDK 的一般方法
1、假如想要使用foo这个模块,先要 #include <foo.h>, 然后链接 /system/lib/libfoo.so 。
(在 Android.mk 文件中加入 LOCAL_LDLIBS := -lfoo)
ndk-build 会自动链接 C库、数学库、C++库
Android 1.5 以上的系统,下面这些库可用:
1、C库(这个C库包含多线程支持,所以不需要指定 -lpthread,也不需要指定 -lrt )
注意:内核头文件很没有稳定下来(今后可能变动),这些头文件是 <linux/*.h> 和 <asm/*.h>
2、数学库(也不需要指定 -lm)
3、C++库: 目前只有这些头文件可用。(不需要指定 -lstdc++ ,是自动链接的)
<cstddef> <new> <utility> <stl_pair.h>
4、Android log:
<android/log.h> android系统的log功能
要用这个API,需要指定 LOCAL_LDLIBS := -llog
5、zlib库:
<zlib.h> 和 <zconf.h>
链接: -lz ( /system/lib/libz.so)
http://www.zlib.net/manual.html
6、动态连接器库:
<dlfcn.h>
这个库提供的函数例如: dlopen()/dlsym()/dlclose()
LOCAL_LDLIBS := -ldl ( /system/lib/libdl.so)
---------------------- 以上由 android-3提供 ---------------------------------
1、OpenGL ES 1.x 库
<GLES/gl.h> 和 <GLES/glext.h>
LOCAL_LDLIBS := -lGLESv1_CM.so( /system/lib/libGLESv1_CM.so)
<uses-feature> ( http://developer.android.com/guide/topics/manifest/uses-feature-element.html)
----------------------- 以上是 android-4 新增的NDK API -------------------------
1、OpenGL ES 2.0
<GLES2/gl2.h> 和 <GLES2/gl2ext.h>
LOCAL_LDLIBS := -lGLESv2.so ( /system/lib/libGLESv2.so)
<uses-feature>
注意: 目前模拟器还不支持这个库
--------------------------以上是 android-5 新增的内容 ------------------------------
1、jnigraphics 库
一个小型的C语言库,提供对Java中的 bitmap 对象的操作。
包含: <android/bitmap.h>
链接: LOCAL_LDLIBS += -ljnigraphics
典型用法:
a) 用 AndroidBitmap_getInfo() 函数从位图句柄(从JNI得到)获得信息(宽度、高度、像素格式)
b) 用 AndroidBitmap_lockPixels() 对像素缓存上锁,即获得该缓存的指针。
c) 用C/C++ 对这个缓冲区进行读写
d) 用 AndroidBitmap_unlockPixels() 解锁
------------------------ 以上是 android-8 新增 -----------------------------
1、OpenSL ES 本地音频库
头文件: <SLES/OpenSLES.h> 和 <SLES/OpenSLES_Platform.h>
链接: LOCAL_LDLIBS += -lOpenSLES (libOpenSLES.so)
----------------------- 以上是 android-9 新增的 -------------------------------
从android-9 开始,就可以完全用C/C++来写android程序了(完全脱离java)
但是,仍然没有脱离java虚拟机,许多东西还是需要通过jni来访问 (参考 docs/NATIVE-ACTIVITY.html )
头文件:
<android/native_activity.h>
1、活动(Activity)生命期的管理
头文件: <android/looper.h> <android/input.h> <android/keycodes.h> <android/sensor.h>
2、监听事件和传感器
头文件: <android/rect.h> <android/window.h> <android/native_window.h> <android/native_window_jni.h>
3、窗口管理(包括对像素缓存加锁、解锁)
头文件: <android/configuration.h> <android/asset_manager.h> <android/storage_manager.h>
<android/obb.h> 对嵌入 apk中的资源(或OBB文件)进行只读的、直接访问。
OBB(Opaque Binary Blob)文件,新特性,允许把较大的数据放在apk之外(对于游戏程序有用)
上面提到的头文件在 "libandroid.so" 共享库中。
链接方法: LOCAL_LDLIBS += -landroid