MyException - 我的异常网
当前位置:我的异常网» Android » Android.mk资料语法规范

Android.mk资料语法规范

www.MyException.Cn  网友分享于:2013-07-02  浏览:12次
Android.mk文件语法规范
序言:
-------------

此文档旨在描述Android.mk文件的语法,Android.mk文件为Android NDK(原生开发)描述了你C/C++源文件。
为了明白下面的内容,你必须已经阅读了docs/OVERVIEW.TXT的内容,它解释了Android.mk文件扮演的角色
和用途。

概述:
---------


写一个Android.mk文件是为了向生成系统描述你的源代码。更明确的说:

- 这个文件实际上是GNU Make文件的一小片段,它会被生成系统解析一次或多次。
因此,你应该在Android.mk里尽量少地声明变量,而不要误以为在解析的过程中
没有任何东西被定义。

- 该文件的语法的明的人为了让你能将你的源代码组织为组件(module).一个组件指的是下面的一项:
     - 一个静态库(static library)
     - 一个共享库(shared library)

  
只有一个动态库会被安装/拷贝至你的application package中。但是静态库可用来
生成动态库。

你可以在每个Android.mk文件定义一个或多个组件,并且我可以在几个组件中使用
相同的源文件。


- 生成系统为你处理了一些琐碎之事。比如,在你的Android.mk里,你不须要列出头文件或
列出生成的文件之间的明确认依赖关系。NDK生成系统会为你自动生成。

这也意味着,当更新至新的NDK版本时,你能得到新的工具链/平台支持(toolchain/platform support)
的好处,而无须修改你的android.mk文件。

需要注意的是,此语法与完全开源的Android平台的Android.mk文件的语法非常相似,但使用它们的
生成系统的实现不同,这个为了让开发者能更容易的复用“外部”库的源代码。


简单例子:
---------------


在详细描述语法之前,让我们探究一个简单的“hello JNI”例子,它的文件位于:
    apps/hello-jni/projec

这里,我们能看到:

- 放有Java源文件的src文件夹。

- 放有本地源文件,即jni/hello-jni.c的jni文件夹。

    这个源文件实现一个简单的共享库。这个共享库有一个本地方法(native method),它将一个字符串
    返回给虚拟机应用(著:即Java层应用程序)

- jni/Anroid.mk文件为NDK生成系统描述了这个共享库。它的内容为:

   ---------- cut here ------------------
   LOCAL_PATH := $(call my-dir)

   include $(CLEAR_VARS)

   LOCAL_MODULE    := hello-jni
   LOCAL_SRC_FILES := hello-jni.c

   include $(BUILD_SHARED_LIBRARY)
   ---------- cut here ------------------

现在,让我们逐行解释:

LOCAL_PATH := $(call my-dir)

每个Android.mk文件都必须以定义LOCAL_PATH变量开始。其目的是为了定位源文件的位置。在这个例子,
生成系统提供的宏函数(macro function)‘my-dir'用来返回当前路径(即放有Android.mk文件的文件夹)

include $(CLEAR_VARS)

CLEAR_VARS变量是生成系统提供的,它指向一个特殊的GNU Makefile.这个Makefile将会为你自动清除
许多名为LOCAL_XXX的变量(比如:LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_STATIC_LIBRARIES,等),
但LOCAL_PATH是例外,它不会被清除。这些变量的清除是必须的,因为所有的控制文件是在单一的GNU make
执行环境中解析的,在这里所有的变量都是全局的。

LOCAL_MODULE := hello-jni

为了在你的Android.mk文件标识每个组件,必须定义LOCAL_MODULE变量。这个名字必须要唯一的并且不能
包含空格。注意:生成系统会自动地为相应生成的文件加入前缀或后缀。换言之,一个名叫foo的共享库组件
会生成'libfoo.so'.

重要注意事项:
如果你把组件取名为‘libfoo',生成系统将不会加上‘lib'前缀,还是
生成libfoo.so。这是为了支持源于Android平台源代码的Android.mk文件。

LOCAL_SRC_FILES := hello-jni.c

LOCAL_SRC_FILES变量必须包含一系列将被构建和组合成组件的C/C++源文件。注意:你
不需要列出头文件或include文件,因为生成系统会为你自动计算出源文件的依赖关系。
仅仅列出那些将直接传给编译器的源文件足矣。


注意,默认的C++源文件的扩展名是‘.cpp'。但你可以通过定义LOCAL_DEFAULT_EXTENSION
来指定一个扩展名。别忘了扩展名开始的那一点(比如,‘.cxx’,能行,但‘cxx'不行)。

include $(BUILD_SHARED_LIBRARY)

生成系统提供的BUIL_SHARED_LIBRARY变量指向一个GNU Makefile脚本,这个脚本主管
收集在最近的一次#include $(CLEAR_VARS)(著:即清除'本地'变量)之后你所定义的
LOCAL_XXX变量的信息,并决定生成什么,如何准确的生成。BUILD_STATIC_LIBRARY可
生成一个静态库。

There are more complex examples under apps/, with commented
Android.mk files that you can look at.
在apps文件下有一些复杂点的例子,它带有注释的Android.mk文件以供你学习。


参考:
-----------

以下列出你在Android.mk里应该依赖或定义的变量。你能定义其它变量,但下列的变量名是
由NDK生成系统保留的。

- 以LOCAL_ 开头的变量名 (比如,LOCAL_MODULE)
- 以PRIVATE_ ,NDK_ 或 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 ------------------
 

So, here we go:


NDK提供的变量:
- - - - - - - - - - - - - -

下列的这些GNU Make变量是在你的Android.mk被解析之前,就被生成系统事先定义
的了.注意,在某些情况下,NDK可能会多次解析你的Android.mk,每次对其中一些变量的
定义不同。

CLEAR_VARS
    指向一个生成脚本,这个脚本取消几乎所有LOCAL_XXX变量的定义(译者注:除了LOCAL_PATH)。
    在开始描述一个新的组件之前,你必须include这个脚本,e.g.:
   
      include $(CLEAR_VARS)
   
   
BUILD_SHARED_LIBRARY
   指向一个生成脚本,这个脚本通过LOCAL_XXX变量收集关于组件的信息,并决定如何
   根据你列出来的源文件生成目标分享库。注意,在include这个脚本文件之前你必须
   至少已经定义了LOCAL_MODULE和LOCAL_SRC_FILES。用法举例:
     include $(BUILD_SHARED_LIBRARY)
    
   注意,这会生成一个名为 lib$(LOCAL_MODULE).so的文件。(译者注:$(BUILD_SHARED_MODULE)为文件名)

   
BUILD_STATIC_LIBRARY
    与BUILD_SHARED_LIBRARY类似,但用来生成目标静态库。静态库不会被拷贝至你的
    project/packages文件夹下,但可用来生成分享库(参考 LOCAL_STATIC_LIBRARIES
    和LOCAL_STATIC_WHOLE_LIBRARIES,将在后面描述)
    用法示例:

       include $(BUILD_STATIC_LIBRARY)

    注意,这会生成一个方件名叫lib$(LOCAL_MODULE).a
  

TARGET_ARCH
   目标CPU的名字,在完整的Android开源代码的生成中指定。对于基于ARM兼容的CPU,
   它被指定为'arm',与CPU架构的修订无关。
   
  
TARGET_PLATFORM
   当解析该Android.mk文件时用它来指定Andoid目标平台的名称。譬如,'android-3'与
   Android 1.5系统镜像相对应。若要了解所有的平台名称及其相应的Android系统镜像,
   请阅读docs/STABLE-APIS.TXT

   
TARGET_ARCH_ABI
    当解析该Android.mk时,CPU+ABI的名称。目前只有一个值。
    (译者注:ABI,Application Binary Interface,二进制应用程序接口)

       armeabi    For Armv5TE
      
       armeabi    指定Armv5TE
         
    注意:到NDK 1.6_r1为止,仅简单的定义这个变量为'arm'。但为了更好地配合
    Android平台的内部使用,该值已重定义。
   
    关于ABI与相应的兼容问题更多详情,请阅读docs/CPU-ARCH-ABIS.TXT

    未来的NDK版本将会引入其它的平台的ABI并会有不同的名称。注意,所有基于ARM的ABI会
    使TARGET_ARCH定义为'arm',但可能拥有不同的TARGET_ARCH_ABI
  
   
TARGET_ABI  
    目标平台与abi的连接,它实际上被定义为 $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI),
    当你想在一个真实的装置上测试特定的目标系统镜像时,它就很有用了。
   
    默认下,它的值为'android-3-armeabi'
   
    (在Android NDK 1.6_r1及之前的版本,它的默认值为'android-3-arm')
   
  

NDK提供的宏函数:
----------------------------

以下是一些GNU Make的宏‘函数’,必须通过这样的形式调用:'$(call <function>)'。
函数返回文本信息。
       
my-dir
    返回放置当前Android.mk的文件夹相对于NDK生成系统根目录的路径。可用来
    在Android.mk的开始处定义LOCAL_PATH的值:
   
       LOCAL_PATH := $(call my-dir)     

       
all-subdir-makefiles
      返回‘my-dir’子目录下的所有Android.mk。比如,代码的结构如下:
     sources/foo/Android.mk
        sources/foo/lib1/Android.mk
        sources/foo/lib2/Android.mk
       
    如果sources/foo/Android.mk里有这样一行:
       
        include $(call all-subdir-makefiles)
   
    那么,它将会自动地includesources/foo/lib1/Android.mk和sources/foo/lib2/Android.mk
   
    这个函数能将深层嵌套的代码文件夹提供给生成系统。注意,默认情况下,NDK仅在
    source/*/Android.mk里寻找文件。

   
this-makefile
     返回当前Makefile(译者注:指的应该是GNU Makefile)的路径(即,这个函数是在哪里调用的)


parent-makefile
     返回在列入树(inclusion tree)中的父makefile的路径。
    即,包含当前makefile的那个makefile的路径。 


grand-parent-makefile
    猜猜看...(译者注:原文为Guess what...)


组件描述相关的变量:
- - - - - - - - - -


以下的变量是用来向生成系统描述你的组件的。你应该在'include $(CLEAR_VARS)'
和'include $(BUILD_XXXXX)'之间定义其中的一些变量。正如在前面所说的,$(CLEAR_VARS)
是一个将会取消所有这些变量的脚本,除非在对变量的描述时有显式的说明。

   
LOCAL_PATH
   这个变量用来设置当前文件的路径。你必须在Android.mk的开始处定义它,比如:
    
    LOCAL_PATH := $(call my-dir)
   
   这个变量不会被$(CLEAR_VARS)消除,所以每个Android.mk仅需一个定义(以防你在
   同一个文件里定义几个组件)。
 
   
LOCAL_MODULE
   定义组件的名称。对于所有的组件名,它必须是唯一,且不能包含空格。
   在include $(BUILD_XXX)之前你必须定义它。
 
   这个组件名决定生成的文件(译者注:即库名)。比如,lib<foo>,即这个组件的名称
   为<foo>。但是在你的NDK生成文件(不管是Android.mk还是Application.mk)中
   你只能通过‘正常’的名称(如,<foo>)来引用其它的组件。
 
         
LOCAL_SRC_FILES
   用它来定义所有用来生成组件的源文件。仅须列出传给编译器的文件,因为
   生成系统会自动地计算它们的相互依赖关系。
 
   注意,所有文件名都是相对于LOCAL_PATH的,你可以用到路径组件(path component)
   如:
     LOCAL_SRC_FILES := foo.c \ (译者注:‘\’为连接符)
                         toto/bar.c

       
LOCAL_CPP_EXTENSION
   这是一个可选的变量,可用它来指明C++源文件的扩展名。默认情况下是'.cpp',
   但你可以改变它。比如:
   
     LOCAL_CPP_EXTENSION := .cxx

     
   
LOCAL_C_INCLUDES
   一个相对于相对于NDK*根*目录可选的路径名单,当编译所有的源文件(C,C++和汇编)时,
   它将被添加进include搜索路径。例如:
  
      LOCAL_C_INCLUDES := sources/foo
 
     或者甚至:
    
      LOCAL_C_INCLUDES := $(LOCAL_PATH)/../foo


LOCAL_CFLAGS
    一个可选的编译标记集,在生成C与C++源文件时,将解析它。
   
    对指定额外的宏定义或编译选项很有用。
              
    重要:不要试图改变你Android.mk里的optimization/debuggin level,通过
          在你的Android.mk里指定合适的信息,它将被自动处理,并使NDK生成
          调试时可用的有用的数据文件。
         
    注意:在android-ndk-1.5_r1,相应的标记(flags)只适用于C源文件,对C++
        源文件并不适用。为了适用于完整的Android生成系统的特性,已作了修
        正。(现在,你可以使用LOCAL_CPPFLAGS为C++文件指定标记)

LOCAL_CXXFLAGS
    LOCAL_CPPFLAGS的别名。注意,不建议使用这个变量,因为在未来的NDK版本中,
    它可能会消失。

LOCAL_CPPFLAGS
     一个可选的编译标记集,*仅*在生成C++源文件时解析它。在编译器的命令行里
     它将在LOCAL_CFLAGS之后出现。

    注意:在android-ndk-1.5_r1,相应的标记(flags)适用于C与C++源文件。
        为了适用于完整的Android生成系统的特性,已作了修
        正。(现在,你可以使用LOCAL_CFLAGS为C和C++源文件指定标记)

LOCAL_STATIC_LIBRARIES
    一份static libraries组件的名单(以BUILD_STATIC_LIBRARY的方式生成),它将被
    连接到欲生成的组件上。这仅在生成shared library组件时有意义。(译者注:将指定
    的一个或多个static library module转化为一个shared library module)

LOCAL_SHARED_LIBRARIES
    一份该组件在运行期依赖于它的shared libraries *组件*。在连接时间(link time)里
    与及为该生成的文件嵌入相应的信息都要用到它。

    注意,它并不将这份组件名单添加入生成图表(build graph)。即,在你的Android.mk
    里,你仍应该将它们加入到你的应用程序要求的组件。

LOCAL_LDLIBS
    一份能在生成你的组件时用到的额外的连接器标记(linkerflags)的名单。在传递
    有“-l”前缀的特殊系统库的名称时很有用。比如,下面的语句会告诉连接器在装载
    时间(load time)里生成连接到/system/lib/libz.so的组件。

      LOCAL_LDLIBS := -lz

    若想知道在这个NDK版本可以连接哪些暴露的系统库(exposed system libraries),
    请参见docs/STABLE-APIS。

LOCAL_ALLOW_UNDEFINED_SYMBOLS
    缺省值情况下,当尝试生成一个shared library遇到没有定义的引用时,会导致“undefined
    symbol”error。这对在你的源代码里捕捉bugs有很大的帮助。
   
    但是,因为一些原因你须要disable这个检查,将这个变量设置为'true’。注意,相应
    的shared library可能在运行期装载失败。

LOCAL_ARM_MODE
    缺省值情况下,ARM目标二进制将会以‘thumb’模式生成,这时每个指令都是16-bit宽的。
    如果你想强迫组件的object文件以‘arm’(32位的指令)的模式生成,你可以将这个变量
    定义为'arm'。即:

      LOCAL_ARM_MODE := arm

    注意,你也可以通过将‘.arm’后缀添加到源文件名字的后面指示生成系统将指定的
    源文件以arm模式生成。例如:
   

       LOCAL_SRC_FILES := foo.c bar.c.arm

    告诉生成系统总是以arm模式编译‘bar.c’,但根据LOCAL_ARM_MODE的值生成foo.c

    注意:在你的Application.mk里将APP_OPTIM设置为'debug',这也会强迫生成ARM二进制
    代码。这是因为工具链的调度器有bugs,它对thumb码的处理不是很好。

文章评论

60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
10个调试和排错的小建议
10个调试和排错的小建议
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
一个程序员的时间管理
一个程序员的时间管理
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
我的丈夫是个程序员
我的丈夫是个程序员
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
那些争议最大的编程观点
那些争议最大的编程观点
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
程序员应该关注的一些事儿
程序员应该关注的一些事儿
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
程序员的鄙视链
程序员的鄙视链
中美印日四国程序员比较
中美印日四国程序员比较
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
每天工作4小时的程序员
每天工作4小时的程序员
代码女神横空出世
代码女神横空出世
 程序员的样子
程序员的样子
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
我是如何打败拖延症的
我是如何打败拖延症的
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
漫画:程序员的工作
漫画:程序员的工作
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
编程语言是女人
编程语言是女人
程序员都该阅读的书
程序员都该阅读的书
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
程序员必看的十大电影
程序员必看的十大电影
为什么程序员都是夜猫子
为什么程序员都是夜猫子
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序员和编码员之间的区别
程序员和编码员之间的区别
鲜为人知的编程真相
鲜为人知的编程真相
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
总结2014中国互联网十大段子
总结2014中国互联网十大段子
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
旅行,写作,编程
旅行,写作,编程
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有