一、Android.mk简介

在Linux下,可以通过Makefile来对源码工程进行管理,Android.mk文件是Makefile的一小部分,它用来对Android程序进行编译。Android.mk文件中描述了哪些C文件将被编译且指明了如何编译。Android.mk文件用来告知NDK Build 系统关于Source的信息。

Android.mk在开发中一般会有以下几种用法:

1、编译可执行程序

2、编译动态库或静态库

3、预编译文件(APK或Java库)


二、语法

首先看一个最简单的Android.mk的例子:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := hello-jni

LOCAL_SRC_FILES := hello-jni.c

include $(BUILD_SHARED_LIBRARY)


讲解如下:

LOCAL_PATH := $(call my-dir)

每个Android.mk文件必须以定义LOCAL_PATH为开始。它用于在开发tree中查找源文件。

my-dir 则由Build System提供。返回包含Android.mk的目录路径。

include $(CLEAR_VARS) 

CLEAR_VARS 变量由Build System提供。并指向一个指定的GNU Makefile,由它负责清理很多LOCAL_xxx.

例如:LOCAL_MODULE, LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES等等。但不清理LOCAL_PATH.

这个清理动作是必须的,因为所有的编译控制文件由同一个GNU Make解析和执行,其变量是全局的。所以清理后才能避免相互影响。

LOCAL_MODULE    := hello-jni 

LOCAL_MODULE模块必须定义,以表示Android.mk中的每一个模块。名字必须唯一且不包含空格。

Build System会自动添加适当的前缀和后缀。例如,foo,要产生动态库,则生成libfoo.so. 但请注意:如果模块名被定为:libfoo.则生成libfoo.so. 不再加前缀。

LOCAL_SRC_FILES := hello-jni.c 

LOCAL_SRC_FILES变量必须包含将要打包如模块的C/C++ 源码。

不必列出头文件,build System 会自动帮我们找出依赖文件。

缺省的C++源码的扩展名为.cpp. 也可以修改,通过LOCAL_CPP_EXTENSION。

include $(BUILD_SHARED_LIBRARY) 

BUILD_SHARED_LIBRARY:是Build System提供的一个变量,指向一个GNU Makefile Script。

它负责收集自从上次调用include $(CLEAR_VARS) 后的所有LOCAL_XXX信息。并决定编译为什么。


BUILD_STATIC_LIBRARY:编译为静态库。

BUILD_SHARED_LIBRARY :编译为动态库

BUILD_EXECUTABLE:编译为Native C可执行程序   

BUILD_PACKAGE(既可以编apk,也可以编资源包文件,但是需要指定LOCAL_EXPORT_PACKAGE_RESOURCES:=true)

BUILD_JAVA_LIBRARY

BUILD_STATIC_JAVA_LIBRARY(java静态库)


静态库就是直接将需要的代码连接进可执行程序; 动态库就是在需要调用其中的函数时,根据函数映射表找到该函数然后调入堆栈执行

静态库可执行文件本身比较大,但不必附带动态库 动态库可执行文件本身比较小,但需要附带动态库


三、总结

Android.mk中三个基本元素: 1、源码文件 :指定源码文件名和文件所在路径。 2、目标文件 :指定目标文件名 3、编译方式 :编译成可执行文件还是动态库或静态库。