NDK里有个例子: android-ndk-r10/samples/module-exports/jni
一看就懂了android
———————————————————————————–架构
从r5版本开始,就支持预编译的库(共享和静态). 也就是说在你的应用中,可包含和使用 预先编译的库。函数
这个功能的用处
1. 你想分发你本身的库给第3方 NDK开发者,但不想把源码给他们
2. 你想使用本身的预编译的库 来加速项目的Build过程。ui
声明一个预编译的库模块
每一个预编译的库,都必须声明为一个独立的模块 给ndk build系统。ip
目录结构开发
mylib --Android.mk --libfoo.so
Android.mk的内容编译器
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so include $(PREBUILT_SHARED_LIBRARY)
注意事项
1. 每一个预编译的模块都必须有一个名字, 好比上面取的名字是 foo-prebuilt
模块 名字 能够跟 预编译的库的名字 不同(好比库的名字是 libfoo, 模块的名字是 foo-prebuild)
2. 设置 LOCAL_SRC_FILES 为你提供的预编译库的 路径。注意,这个路径 是相对于 LOCAL_PATH的。 听说也在 LOCAL_PATH/lib 目录里找源so.源码
另外: 若是你提供的库有多个ABI的版本,还要有点技巧,后面会提到。编译
3. 包含 PREBUILT_SHARED_LIBRARY (提供共享库) ; 或者 包含 PREBUILT_STATIC_LIBRARY(提供静态库)class
在其余模块中 引用上面准备好的预编译模块
只需添加LOCAL_SHARED_LIBRARIES(或者 LOCAL_STATIC_LIBRARIES)声明 到你的 Android.mk中就好了
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-user LOCAL_SRC_FILES := foo-user.c LOCAL_SHARED_LIBRARIES := foo-prebuilt #LOCAL_LDLIBS := -lm -llog include $(BUILD_EXECUTABLE)
惟一要注意的是,引用 模块名(foo-prebuilt), 而不是库名(libfoo)
为预编译的库 输出头文件
在实际应用中, foo-user.c会依赖于 同库文件一块儿分发的头文件(foo.h)中声明的函数或变量
也就是说,在 foo-user.c 将会有以下代码
#include <foo.h>
构建你的foo-user模块时,必须提供 预编译模块的 头文件 以及 头文件的包含路径 给编译器。
假设头文件爱你 放在 预编译模块目录下的 include 目录, 咱们能够在预编译模块的Android.mk中使用export
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include include $(PREBUILT_SHARED_LIBRARY)
LOCAL_EXPORT_C_INCLUDES 能够让 别的引用模块 找到 适合的头文件
别的引用模块,将在 本身的 Android.mk里用 LOCAL_C_INCLUDE 来找(好像不用声明这个, LOCAL_LDFLAGS也不用)
多种ABI
armeabi 目标CPU是ARM v5 TE或者以后的架构 armeabi-v7a 目标CPU是 ARM v7或者以后的架构 x86 mips
须要修改 预编译模块里定义的 LOCAL_SRC_FILES
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so