仅仅要涉及JNI开发都涉及到Android.mk编写,它也是一种makefile语言.

以上一篇博客中提供的project为例!

<1> : 信息打印 : 既然是一种简易语言那么首先应该知道可以打印脚本信息的语法部分:一个是基本信息类型,一个是警告,错误类型

$(info TEXT......) 这个函数运行的时候,会输出: TEXT... ...

$(error TEXT......)
这个函数被运行的时候,会输出:TEXT......,而且终止make的运行.
$(warning TEXT......)
这个函数被运行的时候,会输出:TEXT......,可是make会继续运行下去.

仅仅要在Android.mk中加入上面的部分,就能够打印Android.mk文件里基本信息.

比如:

LOCAL_PATH := $(call my-dir)
$(warning $(LOCAL_PATH))

build so库时,控制台打印出:

jni/Android.mk:2: jni

<2> : Android.mk的树形组织结构从顶究竟链接 : 假设大部分c库都在jni/libmp3lame/文件夹下,那么一般在libmp3lame子文件夹下也最好写一个Android.mk的文件,事实上android的jni是遵循了linux的文件树管理方式,比方我在上面的libmp3lame文件夹下新建一个Android.mk文件:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := lamejni

LOCAL_SRC_FILES := bitstream.c \
encoder.c \
fft.c \
gain_analysis.c \
id3tag.c \
lame.c \
mpglib_interface.c \
newmdct.c
LOCAL_SRC_FILES += presets.c \
psymodel.c \
quantize_pvt.c \
quantize.c \
reservoir.c \
set_get.c \
tables.c \
util.c
LOCAL_SRC_FILES += takehiro.c \
vbrquantize.c \
VbrTag.c \
version.c
LOCAL_SRC_FILES += xmm_quantize_sub.c LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)

然后在jni根文件夹Android.mk改动为:

LOCAL_PATH := $(call my-dir)
$(warning $(LOCAL_PATH))
DURIAN_MAKEFILE_DIR := ./libmp3lame
LOCAL_SRC_FILES := durianlame.c durianutils.c include $(LOCAL_PATH)/./$(DURIAN_MAKEFILE_DIR)/Android.mk

当中通过编译器的include 将所须要的mk文件包括进来就可以,当中LOCAL_PATH获取的,其它的后面是路径 :

include $(LOCAL_PATH)/./$(DURIAN_MAKEFILE_DIR)/Android.mk

加入一条打印记录:

$(warning $(DURIAN_MAKEFILE_DIR)/Android.mk)

输出:

jni/Android.mk:8: ./libmp3lame/Android.mk

以下给一个通用的写法:通过给出的子文件夹路径,搜寻全部子文件夹下的Android.mk文件:

include $(foreach m,$(DURIAN_MAKEFILE_DIR),$(LOCAL_PATH)/./$m/Android.mk)
#include $(LOCAL_PATH)/./$(DURIAN_MAKEFILE_DIR)/Android.mk

凝视掉前面的方法.

当然也有第二种solo所有树以下的写法,个人不推荐:

include $(call all-subdir-makefiles)

<3> : 全部相关的c或者cpp文件 : 相同通过遍历指定子文件夹下的方式进行:还是紧接着上面的Android.mk内容进行改动:

DURIAN_C_SRCS_DIR :=$(LOCAL_PATH)
DURIAN_ALL_C_SRCS := $(foreach m,$(DURIAN_C_SRCS_DIR),$(wildcard $m/*.c))
$(info $(DURIAN_ALL_C_SRCS))
LOCAL_SRC_FILES := $(DURIAN_ALL_C_SRCS) #durianlame.c durianutils.c

上面是在LOCAL_PATH文件夹,这个文件夹在根文件夹中就是jni跟文件夹,只是可能非常多子文件夹下Android.mk也有,这个时候LOCAL_PATH的路径就是指向子文件夹,<1>中也给出的调试信息显示也是jni文件夹.在这个文件夹下wildcard后返回这个文件夹下全部的c文件列表信息,

wildcard使用方法:

$(wildcard PATTERN...)
它被展开为已经存在的、使用空格分开的、匹配此模式的全部文件列表。假设不存在不论什么符合此模式的文件。函数会忽略模式字符并返回空.

注意它的返回值,它返回的是一个列表信息.

以下将其改到libmp3lame下的Android.mk文件:

LOCAL_PATH := $(call my-dir)

$(info $(LOCAL_PATH))
include $(CLEAR_VARS) LOCAL_MODULE := lamejni LOCAL_SRC_FILES := bitstream.c \
encoder.c \
fft.c \
gain_analysis.c \
id3tag.c \
lame.c \
mpglib_interface.c \
newmdct.c
LOCAL_SRC_FILES += presets.c \
psymodel.c \
quantize_pvt.c \
quantize.c \
reservoir.c \
set_get.c \
tables.c \
util.c
LOCAL_SRC_FILES += takehiro.c \
vbrquantize.c \
VbrTag.c \
version.c
LOCAL_SRC_FILES += xmm_quantize_sub.c $(info $(LOCAL_SRC_FILES)) LOCAL_LDLIBS := -llog include $(BUILD_SHARED_LIBRARY)

C文件非常多,加入的时候肯定非常麻烦.

能够更改例如以下:

DURIAN_C_SRCS_DIR :=$(LOCAL_PATH)
DURIAN_ALL_C_SRCS := $(foreach m,$(DURIAN_C_SRCS_DIR),$(wildcard $m/*.c))
DURIAN_ALL_C_SRCS := $(subst $(LOCAL_PATH)/,,$(DURIAN_ALL_C_SRCS))
LOCAL_SRC_FILES := $(DURIAN_ALL_C_SRCS)

请注意:

DURIAN_ALL_C_SRCS := $(subst $(LOCAL_PATH)/,,$(DURIAN_ALL_C_SRCS))

subst是将前面的DURIAN_ALL_C_SRCS获取的列表的子文件夹libmp3lame名字所有去掉,读者能够凝视掉这一行,看看打印的LOG信息就知道了.当然在jni根文件夹下也能够使用,更加通用.

有时候要用到其它的so,假设人家仅仅是提供so和so相应的头文件,那么so放到libs以下,头文件通过放到一个单独的文件夹,相同通过上面的方式导入头文件.

<4> : LOCAL_CFLAGS 使用方法:这个标记全然是针对编译器的,宏定义的变相写法.

在某些时候,编译源代码须要定义宏变量,这个时候,我们能够直接在相应的源代码里面去改动,但也有一些情况,我们是没法在别人的源代码里定义宏变量的,这个时候,就须要使用到LOCAL_CFLAGS 了 ,举比例如以下:
Java代码
LOCAL_CFLAGS += -D__FAVOR_BSD
这行代码的作用就是在原有的cflags基础上,再定义一个宏变量__FAVOR_BSD
相似于#define __FAVOR_BSD
LOCAL_CFLAGS: 可选的编译器选项。在编译 C 代码文件的时候使用。

这可能是有
用的,指定一个附加的包括路径(相对于NDK的顶层文件夹),宏定义,或者编译选项。
 注意:不要在 Android.mk 中改变 optimization/debugging 级别。仅仅要在 Application.mk 中指定合适的信息。就会自己主动地为你处理这个问题,在调试期间,会让 NDK自己主动生成实用的数据文件

还是在举一个有实际意义的样例吧:

在Android.mk文件加入:

LOCAL_CFLAGS += -DDURIAN_DEFINE   //定义了该宏,能够在代码中推断

相当于定义了DURIAN_DEFINE的一个宏.

以下详细使用方法:在你的程序里面通过以下的推断是否调用函数getdurianinformation.

#ifdef DURIAN_DEFINE
getdurianinformation();
#endif

因为上面的是网上问得最多的,所以特别提出来,其余的參考我的cnblog博客上的:

http://www.cnblogs.com/MMLoveMeMM/articles/3909809.html

<5> : 书写Android.mk可能须要非常多,可是实际经常使用的函数,能够归结例如以下:

1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符

另一个字符相减的函数subst

当然不同公司和project可能还有很多其它.

05-20 06:06