Android.mk文件语法规范

Android.mk文件语法规范
冲eoeandroid上之底连载,进行局部更新、修改和加亮。
今翻译ANDROID-MK.TXT文件(英文原文件于/development/Ndk/Docs/android-mk.txt)
Android.mk文件语法规范
Introduction:
Android.mk编译文件是用来向Android NDK描述而的C,C++源代码文件的,
这篇文档描述了它们的语法。在阅读下面的内容前面,假得你已读了docs/OVERVIEW.TXT文件,了解了它们的脚色和用途。
概述:
一个Android.mk file用来为编译系统描述您的源代码。具体来说:-该公文是GNU
Makefile的一样小片段,会叫编译系统解析一不善或重复频繁底build系统。因此,您应尽量减少而声明的变量,不要当某些变量在分析过程被莫见面被定义。-这个文件之语法允许把你的源代码组织成模块,一个模块属下列类型之一:
静态库
共享库
除非共享库将于设置/复制到公的运用软件包。虽然静态库能被用来转移共享库。
卿可以以每一个Android.mk
file中定义一个要多只模块,你吗可以当几乎个模块中应用和一个源代码文件。
/*****************************************************************************/
-编译系统为你处理过剩细节问题。例如,你免欲在你的Android.mk中列出头文件和靠文件。NDK编译系统将会见也你活动处理这些题目。这为代表,在晋级NDK后,你应该取得新的toolchain/platform支持,而且免待改你的Android.mk文件。
瞩目,这个语法同公开宣布的Android平台的开源代码很类似,然而编译系统实现他们的法子可是差的,这是假意这样设计之,可以于程序开发人员重用外部库底源代码更易于。

简易的例子:

当叙述语法细节之前,咱们来拘禁一个简短的”hello
world”的事例,比如,下面的文件:
sources/helloworld/helloworld.c
sources/helloworld/Android.mk
‘helloworld.c’是一个JNI共享库,实现返回”hello world”字符串的原生方法。
对应的Android.mk文件会象下面这样:
———- cut here ——————
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= helloworld
LOCAL_SRC_FILES := helloworld.c
include $(BUILD_SHARED_LIBRARY)
———- cut here ——————
好,我们来解释一下这几乎实施代码:
LOCAL_PATH := $(call my-dir)
一个Android.mk
file首先要定义好LOCAL_PATH变量。它用于在支付养中查找源文件。在这例子中,宏函数’my-dir’,
由编译系统提供,用于返回时路(即蕴涵Android.mk file文件之目录)。
include $( CLEAR_VARS)
CLEAR_VARS由编译系统提供,指定为GNU
MAKEFILE为汝免许多LOCAL_XXX变量(例如 LOCAL_MODULE,
LOCAL_SRC_FILES, LOCAL_STATIC_LIBRARIES, 等等…),
除LOCAL_PATH 。这是必要的,因为拥有的编译控制文件还在和一个GNU
MAKE执行环境中,所有的变量都是大局的。
LOCAL_MODULE := helloworld
LOCAL_MODULE变量必须定义,以标识你以Android.mk文件中讲述的每个模块。名称必须是唯一的,而且不含其他空格。注意编译系统会活动发出合适的前缀和后缀,换句话说,一个叫取名也’foo’的共享库模块,将会晤生成’libfoo.so’文件。
着重注意事项
万一您将仓库命名也‘libhelloworld’,编译系统将不见面增长任何的lib前缀,也会见生成libhelloworld.so,这是为支持来源于Android平台的源代码的Android.mk文件,如果您真正用如此做的言辞。
LOCAL_SRC_FILES := helloworld.c
LOCAL_SRC_FILES变量必须含有将要编译打包进模块中的C或C++源代码文件。注意,你不要在此地列出头文件以及含有文件,因为编译系统将见面自行为公追寻有依赖型的文本;仅仅列出直接传送给编译器的源代码文件就哼。【注意,默认的C++源码文件的扩展名是’.cpp’.
指定一个不同之恢宏名吧是可能的,只要定义LOCAL_DEFAULT_CPP_EXTENSION变量,不要忘记开始之略微圆点(也就是是概念也
‘.cxx’,而休是‘cxx’)(当然就等同步我们一般不会见失掉改变其)】
include $(BUILD_SHARED_LIBRARY)
BUILD_SHARED_LIBRARY是编译系统提供的变量,指向一个GNU
Makefile脚本(应该就是当build/core目录下之shared_library.mk),负责采集自从上次调用’include
$(CLEAR_VARS)’以来,定义在LOCAL_XXX变量中的装有消息,并且决定编译什么,如何是地失去举行。并基于其规则变化静态库。同理对于静态库。

/****************************************************************************/

在sources/samples目录下出双重扑朔迷离一点底事例,写起注释的Android.mk文件,你得省。
参考:
当下是一模一样份而应当于Android.mk中依赖或概念的变量列表,您得定义其他变量为祥和运,
可是NDK编译系统保留下列变量名:
-以LOCAL_初始的讳(例如 LOCAL_MODULE)
-以PRIVATE_, NDK_ or APP_开班的名(内部采用)
-小写名字(内部使用,例如’my-dir’)
如你为便利在Android.mk中定义自己之变量,我们建议下MY_前缀,一个略例子:
———- cut here ——————
MY_SOURCES := foo.c
ifneq ($(MY_CONFIG_BAR),)
MY_SOURCES += bar.c
endif
LOCAL_SRC_FILES += $(MY_SOURCES)
———- cut here ——————


这些GNU Make 变量在你的Android.mk文件解析之前,就由编译系统定义好了。
留意在少数情况下,NDK可能分析Android.mk几涂鸦,每一样涂鸦某些变量的概念会生出例外。
CLEAR_VARS
针对一个编译脚本,几乎拥有非定义之LOCAL_XXX变量都于”Module-description”节被列有。
汝要在起来一个新模块之前包含这个本子。include $(CLEAR_VARS)
BUILD_SHARED_LIBRARY
针对编译脚本,收集所有的公在LOCAL_XXX变量中提供的音,并且决定如何将您列有之源代码文件编译成一个共享库。注意,你必至少在蕴藏这个文件前定义LOCAL_MODULE和LOCAL_SRC_FILES,使用例子:
include $(BUILD_SHARED_LIBRARY)
在意及时将颇成一个曰也lib$(LOCAL_MODULE).so的文件。
BUILD_STATIC_LIBRARY
一个BUILD_SHARED_LIBRARY变量用于编译一个静态库。静态库不会见复制到您的project/packages中,诞生能够用于编译共享库,(看下描述的LOCAL_STATIC_LIBRARIES
and LOCAL_STATIC_WHOLE_LIBRARIES)
采用例子:
include $(BUILD_STATIC_LIBRARY)
瞩目,这将会见转移一个名吧lib$(LOCAL_MODULE).a的文件。
TARGET_ARCH
对象CPU平台的名,如同在android开放源码中指定的那么。如果是’arm’,表示一旦生成ARM兼容的命,与CPU架构的修订版无关。
TARGET_PLATFORM
Android.mk解析的时刻,目标Android平台的名字.详情可参看/development/ndk/docs/stable-apis.txt.
    android-3      -> Official Android 1.5 system images
    android-4      -> Official Android 1.6 system images
    android-5      -> Official Android 2.0 system images
TARGET_ARCH_ABI
暂时只支持有限只value,armeabi和armeabi-v7a。在今日底版中一般将立即半单价值简单的概念也arm,通过android
平台中间针对它们再也定义来获取更好的匹配。
另外的ABI将以后头的NDK版本被介绍,它们会发出例外的讳。注意有基于ARM的ABI都见面拿’TARGET_ARCH’定义成‘arm’,但是会来例外的‘TARGET_ARCH_ABI’
TARGET_ABI
  目标平台与ABI的整合,它实际上为定义成$(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)
在您想使当真的配备受到对一个专门之目标体系进行测试时,会来因此。在默认的景象下,它会是’android-3-arm’。
/*****************************************************************************/
下是GNU Make ‘功能’宏,必须透过利用’$(call
<function>)’来求值,他们回文本化的消息。
my-dir
返时Android.mk所在的目路径,相对于NDK编译系统的顶层。这是行得通之,在Android.mk文件的启这样定义:
LOCAL_PATH := $(call my-dir)
all-subdir-makefiles
   返回一个在当前’my-dir’路径的子目录列表。例如,看下的目层次:
sources/foo/Android.mk
sources/foo/lib1/Android.mk
sources/foo/lib2/Android.mk
如若sources/foo/Android.mk包含一行:
include $(call all-subdir-makefiles)
那么它们就是见面活动包含sources/foo/lib1/Android.mk
和sources/foo/lib2/Android.mk
这项功能用于向编译系统提供好层次嵌套的代码目录层次。注意,在默认情况下,NDK将会只是找于sources/*/Android.mk中的文件。
this-makefile
返时Makefile的门径(即是函数调用的地方)
parent-makefile
  返回调用树被父Makefile路径。即蕴涵当前Makefile的Makefile路径。
grand-parent-makefile
猜猜看…
/*****************************************************************************/
模块描述变量:
下的变量用于向编译系统描述您的模块。你该定义在’include
$(CLEAR_VARS)’和’include
$(BUILD_XXXXX)’之间定义。正而前写的那么,$(CLEAR_VARS是一个剧本,清除所有这些变量,除非在讲述负显式注明。
LOCAL_PATH
  这个变量用于为起当下文件之路子。你得以Android.mk的初步定义,可以这样以:
LOCAL_PATH := $(call my-dir)
这变量不会见于$(CLEAR_VARS)清除,因此每个Android.mk只需要定义一不良(即使你当一个文书被定义了几单模块的动静下)。
LOCAL_MODULE
这是公模块的名,它必须是绝无仅有的,而且无能够包含空格。你不能不于含无一底$(BUILD_XXXX)脚本之前定义其。模块的名决定了扭转文书的讳,例如,如果一个一个共享库模块的名是<foo>,那么生成文书的名字便是lib<foo>.so。但是,在你的NDK生成文件被(或者Android.mk或者Application.mk),你应该单独涉及(引用)有正常名字的另模块。
LOCAL_SRC_FILES
当下是如果编译的源代码文件列表。只要列出要传送让编译器的文本,因为编译系统自动为您算依赖。
专注源代码文件名称都是对立于LOCAL_PATH的,你可采取路径有,例如:
LOCAL_SRC_FILES := foo.c /
toto/bar.c
在意:在转变文书中都使运用UNIX风格的斜杠(/).windows风格的相反斜杠不会见于科学的拍卖。
LOCAL_CPP_EXTENSION
当下是一个可选变量,用来指定C++代码文件的壮大名,默认是’.cpp’,但是你可以转移她,比如:
LOCAL_CPP_EXTENSION := .cxx
LOCAL_C_INCLUDES
       路径的可选配置,是自从彻底目录开始的,
    all sources (C, C++ and Assembly). For example:
        LOCAL_C_INCLUDES := sources/foo
    Or even:
        LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo
       需要以其余含LOCAL_CFLAGS / LOCAL_CPPFLAGS标志之前。
 LOCAL_CFLAGS
唯独摘的编译器选项,在编译C代码文件的时候使用。
当即或许是行之,指定一个叠加的带有路径(相对于NDK的顶层目录),宏定义,或者编译选项。
 重要信息:不要以Android.mk中改变optimization/debugging级别,只要以Application.mk中指定合适的信,就会自行地也公处理者题材,在调试中,会于NDK自动生成中的数据文件。
LOCAL_CXXFLAGS
Same as LOCAL_CFLAGS for C++ source files
LOCAL_CPPFLAGS
与LOCAL_CFLAGS相同,但是对C 和 C++ source files都适用。
LOCAL_STATIC_LIBRARIES
该链接到之模块的静态库列表(使用BUILD_STATIC_LIBRARY生成),这单对旅享库模块才发含义。
LOCAL_SHARED_LIBRARIES
此模块于运转时要因之共享库模块列表,在链接时索要,在变更文书时置放的对应的信。注意:这不会见附加列出的模块到编译图,也即是,你还是需要在Application.mk中把她增长到程序要求的模块中。
LOCAL_LDLIBS
编译你的模块要采用的附加的链接器选项。这对于用”-l”前缀传递指定库的讳是中的。例如,下面将告诉链接器生成的模块要于加载时刻链接到/system/lib/libz.so
LOCAL_LDLIBS := -lz
看docs/STABLE-APIS.TXT获取你采取NDK发行本会链接到的开之系库列表。
LOCAL_ALLOW_UNDEFINED_SYMBOLS
  默认情况下,在待编译一个共享库时,任何不定义的援将致一个“未定义的记号”错误。这对在您的源代码文件被捕捉错误会有深老的拉。
而是,如果您因一些原因,需要不启动这项检查,把这个变量设为‘true’。注意相应的共享库可能在运作时加载失败。(这个貌似尽量不苟错过而为true)
LOCAL_ARM_MODE
      
默认情况下,arm目标二上前制会以thumb的款式转变(16各),你可由此安装这个变量为arm如果你想您的module是以32号指令的款式。
    ‘arm’ (32-bit instructions) mode. E.g.:
      LOCAL_ARM_MODE := arm
顾你同可以编译的时告诉系统编译特定的种,比如
       LOCAL_SRC_FILES := foo.c bar.c.arm
然便报系统总是将bar.c以arm的模式编译,
Android.mk使用模板
当一个Android.mk中可以变更多个可执行程序、动态库和静态库。
1,编译应用程序的模板:
     #Test Exe
     LOCAL_PATH := $(call my-dir)
     #include $(CLEAR_VARS)
     LOCAL_SRC_FILES:= main.c
     LOCAL_MODULE:= test_exe
     #LOCAL_C_INCLUDES :=
     #LOCAL_STATIC_LIBRARIES :=
     #LOCAL_SHARED_LIBRARIES :=
     include $(BUILD_EXECUTABLE)
(菜鸟级别解释::=是赋值的意思,$是引用某变量的价)LOCAL_SRC_FILES中投入源文件路径,LOCAL_C_INCLUDES
中在所急需包含的峰文件路径,LOCAL_STATIC_LIBRARIES加入所要链接的静态库(*.a)的名称,
LOCAL_SHARED_LIBRARIES中投入所用链接的动态库(*.so)的名称,LOCAL_MODULE表示模块最终之称,
BUILD_EXECUTABLE代表因一个可执行程序的办法展开编译。
2,编译静态库的模板:
     #Test Static Lib
     LOCAL_PATH := $(call my-dir)
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES:= /
               helloworld.c
     LOCAL_MODULE:= libtest_static
     #LOCAL_C_INCLUDES :=
     #LOCAL_STATIC_LIBRARIES :=
     #LOCAL_SHARED_LIBRARIES :=
     include $(BUILD_STATIC_LIBRARY)
相似的以及方面相似,BUILD_STATIC_LIBRARY表示编译一个静态库。
3,编译动态库的模版:
     #Test Shared Lib
     LOCAL_PATH := $(call my-dir)
     include $(CLEAR_VARS)
     LOCAL_SRC_FILES:= /
               helloworld.c
     LOCAL_MODULE:= libtest_shared
     TARGET_PRELINK_MODULES := false
     #LOCAL_C_INCLUDES :=
     #LOCAL_STATIC_LIBRARIES :=
     #LOCAL_SHARED_LIBRARIES :=
      include $(BUILD_SHARED_LIBRARY)
貌似的跟点相似,BUILD_SHARED_LIBRARY表示编译一个共享库。
以上三者的扭转结果个别于如下,generic依实际target会换:
out/target/product/generic/obj/EXECUTABLE
out/target/product/generic/obj/STATIC_LIBRARY
out/target/product/generic/obj/SHARED_LIBRARY
      每个模块的靶子文件夹分别吗:
可执行程序:XXX_intermediates
静态库:      XXX_static_intermediates
动态库:      XXX_shared_intermediates
     
另外,在Android.mk文件中,还足以指定最后之目标设置路径,用LOCAL_MODULE_PATH和LOCAL_UNSTRIPPED_PATH来指定。不同的文件系统路径用以下的庞然大物进行选择:
TARGET_ROOT_OUT:表示根文件系统。
TARGET_OUT:表示system文件系统。
TARGET_OUT_DATA:表示data文件系统。
用法如:
LOCAL_MODULE_PATH:=$(TARGET_ROOT_OUT)

 

转http://blog.csdn.net/pottichu/article/details/5655438