Android编程使用NDK必须创建一个jni文件夹,并且jni文件里一般包含有C/C++的源码文件、Android..mk文件、Application.mk文件(可选),Android.mk文件的编写是重点。 Android.mk文件学习 Android.mk文件告诉编译器将C/C++的源码文件编译成动态库、静态库或者可执行程序,具体的可以参考android-ndk-r9\docs下的文档ANDROID-MK.html。 BUILD_SHARED_LIBRARY 编译成动态库 BUILD_STATIC_LIBRARY 编译成静态库 BUILD_EXECUTABLE 编译生成标准可执行程序 标准的Android.mk文件的实例: #必须以LOCAL_PATH变量开头 LOCAL_PATH := $(call my-dir) #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := hello # C /C++源码 LOCAL_SRC_FILES := hello.cpp #编译生成动态共享库 include $(BUILD_SHARED_LIBRARY) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1. 构建多个动态共享库 一个单独的Android.mk文件可以产生多个共享库模块,在Android.mk文件中定义多个模块即可。 #必须以LOCAL_PATH变量开头 LOCAL_PATH := $(call my-dir) # #模块1 # #清除变量 include $(CLEAR_VARS) #生成模块1的名称 LOCAL_MODULE := hello1 #C++源码 LOCAL_SRC_FILES := hello1.cpp #编译生成共享库 include $(BUILD_SHARED_LIBRARY) # #模块2 # #清除变量 include $(CLEAR_VARS) #生成模块2的名称 LOCAL_MODULE := hello2 #C++源码 LOCAL_SRC_FILES := hello2.cpp #编译生成共享库 include $(BUILD_SHARED_LIBRARY) #产生两个.so动态库文件即hello1.so和hello2.so ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2. 构建静态库 在Android应用程序中很少直接使用静态库,静态库一般是用来构建动态共享库,比如将第三方代码编译成静态库然后并入共享库。 #必须以LOCAL_PATH变量开头。 LOCAL_PATH := $(call my-dir) # #第三方模块AVI库 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := avilib #C源码 LOCAL_SRC_FILES := avilib.cpatform.c #编译生成静态库 include $(BUILD_STATIC_LIBRARY) ################################################################### # #原生模块 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := hello #C源码 LOCAL_SRC_FILES := hello.c #引用第三方静态库avilib LOCAL_STATIC_LIBRARIES := avilib #编译生成共享库 include $(BUILD_SHARED_LIBRARY) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3. 用共享库构建通用模块 当多个共享库与同一个静态库连接时,静态库会产生多个副本,会增加应用程序的大小;因此最好将其编译成动态共享库库,供多个共享库调用。 #必须以LOCAL_PATH变量开头 LOCAL_PATH := $(callmy-dir) # #第三方模块AVI库 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := avilib #C源码 LOCAL_SRC_FILES := avilib.cpatform.c #编译生成动态共享库 include $(BUILD_SHARED_LIBRARY) ################################################################### # #原生模块1 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := hello1 #C源码 LOCAL_SRC_FILES := hello1.c #引用第三方动态共享库avilib LOCAL_SHARED_LIBRARIES := avilib #编译生成动态共享库 include $(BUILD_SHARED_LIBRARY) # #原生模块2 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := hello2 #C源码 LOCAL_SRC_FILES := hello2.c #引用第三方动态共享库avilib LOCAL_SHARED_LIBRARIES := avilib #编译生成动态共享库 include $(BUILD_SHARED_LIBRARY) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4. 使用Prebuilt库 前面的三种库文件的调用都有一个要求:必须将C/C++源码文件包含在NDK项目工程中,自R3以后Android的NDK提供了对Prebuilt库的支持,不需要源码文件就可以发布你的模块给他人使用。 预构建共享库模块的Android.mk文件 #必须以LOCAL_PATH变量开头 LOCAL_PATH := $(call my-dir) # #第三方预构建AVI库 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := avilib #预构建so库 LOCAL_SRC_FILES := libavilib.so #编译生成动态共享库 include $(PREBUILD_SHARED_LIBRARY) 使用Prebuilt共享库 LOCAL_SHARED_LIBRARIES := avilib 说明:还可以编译成PREBUILT_STATIC_LIBRARY类型的Prebuilt静态库 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5. 构建独立的可执行文件 为方便测试和快速原型设计,AndroidNDK支持编译生成独立的可执行文件,不需要打包成APK文件,就可以复制到Android设备中作为Linux应用程序直接执行。 #必须以LOCAL_PATH变量开头 LOCAL_PATH := $(call my-dir) # #模块 # #清除变量 include $(CLEAR_VARS) #生成模块1的名称 LOCAL_MODULE := hello #C++源码 LOCAL_SRC_FILES := hello.cpp #编译生成可执行文件 include $(BUILD_EXECUTABLE) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6. 在多个NDK项目间共享模块 共享avilib文件的Android.mk文件 #必须以LOCAL_PATH变量开头 LOCAL_PATH := $(call my-dir) # #第三方AVI库 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := avilib #C源码 LOCAL_SRC_FILES := avilib.c patform.c #编译生成静态库 include $(BUILD_SHARED_LIBRARY) 使用共享模块的NDK项目工程 # #原生模块 # #清除变量 include $(CLEAR_VARS) #生成模块的名称 LOCAL_MODULE := hello #C源码 LOCAL_SRC_FILES := hello.c #引用第三方动态共享库avilib LOCAL_SHARED_LIBRARIES := avilib #编译生成共享库 include $(BUILD_SHARED_LIBRARY) $(call import-module,transcode/avilib) 为了避免冲突,应该将import-module函数宏放在Android.mk文件的末尾。import-module函数宏默认只搜索<Android NDK>/sources目录,为了让它搜索其他的目录必须设置环境变量NDK_MOUDLE_PATH值为要搜索的目录路径。 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 7. 条件操作 在Android.mk文件中也可以有条件操作,例如在每个体系结构中包含不同源文件: ... ifeq($(TARGET_ARCH),arm) LOCAL_SRC_FILES + = armonly.c else LOCAL_SRC_FILES + = generic.c endif ... Application.mk文件学习 Application.mk文件是AndroidND构建系统使用的可选构建文件。它的目的是描述应用程序需要那些模块;它也定义所有模块的通用变量。 Application.mk文件的例子: #APP_ABI默认为armeabi可以更改,ABI生成二进制文件 #APP_ABI := armeabi mips也可以是多个 #APP_ABI := all 为所有支持的ABI生成二进制文件 APP_ABI := armeabi #生成程序运行支持的平台 APP_PLATFORM := android-8 #对STL的支持 APP_STL := stlport_static #对异常的支持 APP_CPPFLAGS += -fexceptions #对RTTI的支持 APP_CPPFLAGS += -frtti 对Application.mk文件具体的信息可以仔细阅读android-ndk-r9\docs下的文档APPLICATION-MK.html。