Application.mk file syntax specification
Introduction:
------------------
本文档描述Application.mk文件的语法,这个编译文件描述Android应用需要的本地modules。为了便于理解下面的内容,假设你已经阅读了OVERVIEW相关内容,了解了它们的作用以及用法。
在阅读以下文档之前,请先阅读OVERVIEW和Android.mk相关内容。
Overview:
--------------
Application.mk是用来描述你应用程序需要的本地‘modules’(如静态/共享库)。
Application.mk通常放在$PROJECT/jni/Application.mk下,$PROJECT指向你应用程序的工程目录。
另外,也可以放在$NDK/apps的子目录下,例如:
$NDK/apps/<myapp>/Application.mk
<myapp>是用来向NDK编译系统描述你应用程序的一个简短名称(这个名字不会编译到动态库和最终的程序包中)。
Application.mk是一个非常轻量级的GNUMakefile脚本,必须定义一些变量:
APP_PROJECT_PATH
这个变量必须给出你应用程序的工程根目录的绝对路径。这个用来拷贝/安装生成JNI动态库的stripped版本到一个APK生成工具知道的指定位置。
注意$PROJECT/jni/Application.mk是可选的,但是对于$NDK/apps/<myapp>/Application.mk却是强制要求的。
APP_MODULES
这个变量是可选的。如果没有定义,NDK将会采用默认的方式,编译在Android.mk声明的所有modules,同时包含了所有子目录下的Android.mk文件。
如果APP_MODULES定义了,它必须是用空格分开的module名称的列表,这些module的名称就是在Android.mk文件中LOCAL_MODULE定义的。注意NDK将会自动计算module的依赖关系。
注意:在NDK r4中变量的默认行为发生了变化。之前的是:
-在Application.mk中这个变量是强制要求的
-必须显示的列出所有需要的modules。
APP_OPTIM
这个可选的变量可定义在‘release’或者‘debug’中。当编译应用程序的modules的时候,这个用来改变优化级别。
默认是‘release’模式,并生成高级别的二进制文件。‘debug’模式会生成没有优化的二进制文件,这样更容易调试。
注意如果你的应用程序是可调试的(如在manifest的<application>设置android:dubuggable为‘true’),这样默认的就是‘debug’而不是‘release’。这个可以通过设置APP_OPTIM为‘release’来覆盖它。
注意可以同时设置为‘release’和‘debug’,但是在debuggingsessions过程中‘release’编译倾向提供比较少的信息:一些变量进行了优化,不能被检查,代码进行了重新排序使得单步调试代码变得困难,栈的跟踪将变得不可靠,等等。。。
APP_CFLAGS
当编译任何modules中的c或c++源文件的时候,会传递一个C编译标志的集合。这个可以用来改变应用程序需要的module的编译行为,而不需要修改Android.mk文件本身。
重要警告:++++++++++++++++++++++++++++++++++++++++++
+
+ 所有路径必须相对于NDK顶级目录。例如,如果你有下面的设置:
+
+ sources/foo/Android.mk
+ sources/bar/Android.mk
+
+ 在编译的时候,为了在foo/Android.mk中指定你想要添加的‘bar’源文件的路径,你应该使用:
+
+ APP_CFLAGS += -Isources/bar
+ 或者:
+
+ APP_CFLAGS += -I$(LOCAL_PATH)/../bar
+ 使用‘-I../bar’不能工作,因为他等价于‘-I$NDK_ROOT../bar’。
+
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
注意:在android-ndk-1.5_r1中,只能使用在c源文件上,c++不行。这个已经修正来满足整个Android编译系统的要求。
APP_CXXFLAGS
APP_CPPFLAGS的别名,在以后的NDK发布版本中它可能会消失。
APP_CPPFLAGS
只有在编译C++源代码的时候,传递的C++编译标志的集合。
注意:在android-ndk-1.5_r1中,这个可以同时用在c和c++源代码上。这个已经修正来满足整个Android编译系统的要求。你现在可以使用APP_CFLAGS标志应用在c和c++源代码上。
APP_BUILD_SCRIPT
默认情况下,NDK编译系统会查找$(APP_PROJECT_PATH)/jni目录下的Android.mk文件,例如:
$(APP_PROJECT_PATH)/jni/Android.mk
如果你想改变这个默认行为,你可以定义APP_BUILD_SCRIPT指向一个编译脚本。一个不是绝对路径的path总是解释为相对于NDK的顶级目录。
APP_ABI
默认情况下,NDK编译系统将会生成‘armeabi’ABI的机器码。这对应使用浮点运算操作的基于ARMv5TE的CPU。你可以使用APP_ABI选择一个不同的ABI。
例如,为了支持基于ARMv7设备的硬件FPU指令,使用:
APP_ABI := armeabi-v7a
或者支持IA-32指令集,使用:
APP_ABI := x86
或者支持MIPS指令集,使用:
APP_ABI := mpis
或者同时支持所有指令集,使用:
APP_ABI := armeabi armeabi-v7a x86 mpis
或更好,从NDK r7,你可以使用‘all’,表示这个版本的NDK支
持的所有ABIs:
APP_ABI := all
想要了解所有支持的ABIs和关于它们的使用和限制的细节,请阅读CPU-ARCH-ABIs相关内容。
APP_PLATFORM
目标android平台的名称。例如,‘android-3’对应Android 1.5 系统镜像。想要了解完整的平台名称和对应的Android系统镜像,请查看STABLE-APIS相关内容。
APP_STL
默认情况下,NDK编译系统提供最小的C++运行时库(/system/lib/libstdc++.so)的头文件,这个最小的运行时库是由android系统提供。
但是,NDK自带的C++实现,让你能够使用或链接到你的运用程序中。定义APP_STL为下面的一个,例如:
APP_STL := stlport_static --> static STLport library
APP_STL := stlport_shared --> shared STLport library
APP_STL := system --> default C++ runtime library
想要了解这个主题的信息,请阅读CPLUSPLUS-SUPPORT相关内容。
APP_GNUSTL_FORC_CPP_FEATURES
在NDK之前的版本中,一个简单的事实是:运行时使用GNU libstdc++(例如,通过设置APP_STL为‘gunstl_static’或‘gunstl_shared’)会强制在所有生成的机器代码中支持异常和RTTI。这可能在特定的情况下会有问题,但是非常罕见,如,会为工程生成不必要的很大的代码,而这些代码对于这些功能来是不需要的。
这个bug在NDK r7已经修复了,但是意味着,如果你的代码需要使用异常或RTTI,它必须显示的指出,要么在APP_CPPFLAGS,要么在你的LOCAL_CPPFLAGS / LOCAL_CPP_FEATURES定义中。
在NDK r7以及以后的版本中,为了使得对projects的接口更加简单,一种可选的方法是定义APP_GNUSTL_CPP_FEATURES来包含一个或多个下面的这些值:
exceptions -> to enforce exceptions support for allmodules.
rtti ->to enforce rtti support for all modules.
例如,要在NDK r7中得到同样的行为:
APP_GNUSTL_FORCE_CPP_FEATURES:= exceptions rtti
重要:在这里提供这个变量是作为一个便利的工具,使得它转向新版本的NDK更加简单。我们鼓励所有的开发者恰当的修改module的定义,而不要依赖于它。
APP_SHORT_COMMANDS
对于整个工程来说,这个和LOCAL_SHORT_COMMANDS是一样的。请查看Android.mk文档中的内容。
NDK_TOOLCHAIN_VERSION
定义这个变量为4.4.3或4.6来选择GCC编译器的版本。4.6是默认值。
APP_PIE
从Jelly Bean (4.1)开始,Android的动态链接器支持position-independent executables (PIE),用-fPIE进行编译,这个标志会使得通过随机代码的位置来查找内存损坏的bug更加困难。
默认,ndk-build将自动设置这个值为‘true’,如果你的工程targets是Android-16或更高。你可以手工的设置它为‘true’或‘false’。
重要:PIE executables不能运行在Android4.1之前的版本上。
注意这个只能运用在可执行程序上。当编译动态或静态库的时候是不起作用的。
一个非常简单的Application.mk文件如下:
-------------- 分割线 -------------------------
APP_PROJECT_PATH := <pathto project>
-------------- 分割线-------------------------