使用Eclipse进行Android的jni代码开发时,因为使用的是NDK的build方式编译,因此必须编写.mk文件。
首先,介绍一下在Android.mk文件中常用的模块描述变量
1. LOCAL_PATH: 当前文件的路径,必须在 Android.mk 的开头定义,不会被include $(CLEAR_VARS)清除
。一般这样定义:LOCAL_PATH := $(call my-dir)
。但也可以指定目录,如当前目录下名为 src的文件夹,可以写成 LOCAL_PATH := $(call src)
,就可以得到 src 的完整路径。
2. LOCAL_MODULE: 生成的动态库名称,必须唯一且不包含空格;也可以是引用的静态库.a的名称。如LOCAL_MODULE := rtalgthm (在实际生成的动态库文件名中会自动增加lib前缀-librtalgthm.so)
.
3. LOCAL_SRC_FILES:待编译的源文件(C/CPP/.a)。多个C/CPP文件时,文件可以用空格或Tab键进行分割,换行请用”\” ,如LOCAL_SRC_FILES:= cdjpeg.c djpeg.c rdcolmap.c rdswitch.c \ wrbmp.c wrgif.c wrppm.c wrtarga.c
4. LOCAL_STATIC_LIBRARIES:编译使用到的静态库文件名称。
5. LOCAL_SHARED_LIBRARIES: 表示模块在运行时要依赖的共享库(动态库),在链接时就需要,以便在生成文件时嵌入其相应的信息。
6. LOCAL_LDLIBS: 编译模块时要使用的附加的链接器选项。
LOCAL_LDLIBS := -lz表示告诉链接器生成的模块要在加载时刻链接到/system/lib/libz.so
可查看 docs/STABLE-APIS.TXT 获取使用 NDK发行版能链接到的开放的系统库列表。
以上只是部分常用的变量,并没有列举出全部的变量,想要了解其他变量信息的,请自行搜索。接下来,分几种情况介绍一下Android.mk文件的编写。
注:我的JNI代码的布局是这样的:
1. 只编译C/CPP源码
这种情况下的Android.mk文件只需要编译C/CPP源文件即可。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := rtalgthm
LOCAL_SRC_FILES:= algorithm/rt.cpp
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
2. 只编译.a静态库文件
这种情况下的Android.mk文件如下:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libRTECGAlgthm
LOCAL_SRC_FILES := algorithm/$(TARGET_ARCH_ABI)/libRTECGAlgthm.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := rtalgthm
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
注:$(TARGET_ARCH_ABI)可以在编译的时候,动态指定并编译不同CPU架构文件夹下的.a文件。
5. 只编译.so文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libRTECGAlgthm
LOCAL_SRC_FILES := algorithm/$(TARGET_ARCH_ABI)/libRTECGAlgthm.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := rtalgthm
LOCAL_SHARED_LIBRARIES := libRTECGAlgthm
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
4. C/CPP、以及.a(.so)库文件共同编译
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libRTECGAlgthm
LOCAL_SRC_FILES := algorithm/$(TARGET_ARCH_ABI)/libRTECGAlgthm.a #(.so)
include $(PREBUILT_STATIC_LIBRARY) #($(PREBUILT_SHARED_LIBRARY))
include $(CLEAR_VARS)
LOCAL_MODULE := rtalgthm
LOCAL_SRC_FILES:= algorithm/rt.cpp
LOCAL_STATIC_LIBRARIES := libRTECGAlgthm #LOCAL_SHARED_LIBRARIES := libRTECGAlgthm
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
include $(BUILD_SHARED_LIBRARY)
最后介绍Application.mk的内容,关于Application.mk中的变量介绍,可参考此文章
再次贴出我的Application.mk文件
APP_ABI := armeabi-v7a arm64-v8a x86_64
APP_STL := gnustl_static
APP_PLATFORM :=android-23
APP_CPP_FEATURES += exceptions rtti
ifdef APP_DEBUG
ifeq ($(APP_DEBUG),true)
CFLAGS+= -O0 -g
LOCAL_CFLAGS+= -D_DEBUG
APP_OPTIM := debug
else
CFLAGS+= -O2 -g
LOCAL_CFLAGS+= -DNDEBUG
APP_OPTIM := release
endif
endif
因为armeabi-v7a arm64-v8a x86_64这三种CPU架构基本覆盖所有的Android手机,所以我就没有生成所有架构下的.so文件。