详解安卓系统中的Android.mk文件

 更新时间:2015年07月31日 11:30:52   作者:低调小一  
这篇文章主要介绍了详解安卓系统中的Android.mk文件,该文件用来告诉系统关于源代码的编译,需要的朋友可以参考下

概述
    Android.mk文件用来向编译系统描述如何编译你的源代码。更确切地说,该文件其实就是一个小型的Makefile。由于该文件会被NDK的编译工具解析多次,因此应该尽量减少源码中声明变量,因为这些变量可能会被多次定义从而影响到后面的解析。这个文件的语法允许把源代码组织成模块,每个模块属于下列类型之一:

    APK程序:一般的Android程序,编译打包生成apk文件。
    JAVA库:java类库,编译打包生成jar包文件。
    C\C++应用程序:可执行的C/C++应用程序。
    C\C++静态库:编译生产C/C++静态库,并打包成.a文件。
    C\C++共享库:编译生成共享库,并打包成.so文件,有且只有共享库才能被安装/复制到APK包中。


举例
    这里参考了网上一个通用的例子,编译简单的“Hello World”,来说明一下Android.mk编写。例如下面的文件:
1. sources/test/hello.c
2. sources/test/Android.mk
    其中“hello.c”是一个JNI共享库,实现返回“hello world”字符串的原生方法。因此,Android.mk文件内容如下:

  LOCAL_PATH := $(call my-dir) 
  include $(CLEAR_VARS) 
  LOCAL_MODULE := hello 
  LOCAL_SRC_FILES := hello.c 
  include $(BUILD_SHARED_LIBRARY) 

    解释一下这几行代码:
1. LOCAL_PATH := $(call my-dir) : 一个Android.mk文件首先必须定义好LOCAL_PATH变量,用于在开发树中查找源文件。在这个例子中,宏函数my-dir由编译系统提供,用于返回当前路径(即包含Android.mk文件的目录)。
2. include $(CLEAR_VARS):CLEAR_VARS由编译i系统提供,指定让GNU MAKEFILE清除除了LOCAL_PATH变量外的许多LOCAL_***变量(例如:LOCAL_MODULE、LOCAL_SRC_FILES等)。这是非常有必要的,因为所有的编译文件都在同一个GUN MKAE执行环境中,所有的变量都是全局变量,不清除容易引起解析错误。
3. LOCAL_MODULE := hello:LOCAL_MODULE变量必须定义,用来标识在Android.mk文件描述的每一个模块。而且名称必须是唯一的,并且不能包含空格。编译系统会自动产生合适的前缀和后缀,比如一个被命名为hello的共享库模块,将会生成libhello.so文件。如果把库命名为libhello,编译系统将不会添加任何lib前缀,也会生成libhello.so文件。
4. LOCAL_SRC_FILES := hello.c:LOCAL_SRC_FILES变量必须包含将要编译打包进模块中的源代码文件。
5. include $(BUILD_SHARED_LIBRARY):BUILD_SHARED_LIBRARY是编译系统提供的变量,指向一个GNU Makefile脚本(应该就是build/core目录下的shared_library.mk),负责收集自从上次调用include $(CLEAR_VARS)以来,定义在LOCAL_***变量中的所有信息,并且决定编译什么,如何正确地去做,并根据其规则生成静态库。
6. 解释一下Android.mk里变量定义字符":="。“:=”类似于c中的宏,即在定义处明确展开,完全进行文本替换。

模块描述变量
     下面的变量用于向系统描述我们自己的模块,它应该定义在include $(CLEAR_VARS)和include $(BUILD_***)之间。正如前面讲述的那样,$(CLEAR_VARS)是一个脚本,清除所有这些变量,除非在描述中显示注明。
1. LOCAL_PATH:这个变量用于给出当前文件的路径,必须在Android.mk的开头定义,可以这样使用:LOCAL_PATH := $(call my-dir),这样这个变量不会被$(CLEAR_VARS)清除,因为每个Android.mk只需要定义一次(即使一个文件中定义了多个模块的情况下)。
2. LOCAL_SRC_FILES:当前模块包含的所有源代码文件。
3. LOCAL_MODULE:当前模块的名称,这个名称应当是唯一的,并且不能包含空格。模块间的依赖关系就是通过这个名称来引用的。
4. LOCAL_MODULE_CLASS:标识所编译模块最后放置的位置。ETC表示放置在/system/etc.目录下,APPS表示放置在/system/app目录下,SHARED_LIBRARIES表示放置在/system/lib目录下。如果具体指定,则编译的模块不会放到编译系统中,最后会在out对应product的obj目录下的对应目录中。
5. LOCAL_SRC_FILES:这是要编译的源代码文件列表。只要列出要传递给编译器的文件即可,编译系统会自动计算依赖关系。源代码文件路径都是相相对于LOCAL_PATH的,因此可以使用相对路径进行描述。
6. LOCAL_JAVA_LIBRARIES:当前模块依赖的Java共享库,也叫Java动态库。例如framework.jar包。
7. LOCAL_STATIC_JAVA_LIBRARIES:当前模块依赖的Java静态库,在Android里,导入的jar包和引用的第三方工程都属于Java静态库。
8. LOCAL_STATIC_LIBRARIES:当前模块在运行时依赖的静态库的名称。
9. LOCAL_SHARED_LIBRARIES:当前模块在运行时依赖的动态库的名称。
10. LOCAL_C_INCLUDES:c或c++语言需要的头文件的路径。
11. LOCAL_CFLAGS:提供给C/C++编译器的额外编译参数。
12. LOCAL_PACKAGE_NAME:当前APK应用的名称。
13. LOCAL_CERTIFICATE:签署当前应用的证书名称。
14. LOCAL_MODULE_TAGS:当前模块所包含的标签,一个模块可以包含多个标签。标签的值可能是eng、user、debug、development、optional。其中,optional是默认标签。
15. LOCAL_DEX_PREOPT:apk的odex优化开关,默认是false。

    除此之外,Build系统中还定义了一些函数方便在Android.mk中使用,包括:
1. $(call my-dir):获取当前文件夹的路径。
2. $(call all-java-files-under, <src>):获取指定目录下的所有java文件。
3. $(call all-c-files-under, <src>):获取指定目录下的所有c文件。
4. $(call all-Iaidl-files-under, <src>):获取指定目录下的所有AIDL文件。
5. $(call all-makefiles-under, <folder>):获取指定目录下的所有Make文件。
6. $(call intermediates-dir-for, <class>, <app_name>, <host or target>, <common?>):获取Build输入的目标文件夹路径。

相关文章

  • 浅析C语言中堆和栈的区别

    浅析C语言中堆和栈的区别

    堆和栈都是一种数据项按序排列的数据结构。在C语言中是非常重要的知识点,接下来通过本文给大家介绍C语言中堆和栈的区别,感兴趣的朋友一起看下吧
    2016-06-06
  • C/C++读取配置文件的方式小结

    C/C++读取配置文件的方式小结

    这篇文章主要为大家详细介绍了C/C++中读取配置文件的几种常见方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2024-04-04
  • C语言实现通讯录小功能

    C语言实现通讯录小功能

    这篇文章主要为大家详细介绍了C语言实现通讯录小功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • C++实现旋转扫描仪的示例代码

    C++实现旋转扫描仪的示例代码

    旋转扫描仪(Rotating Scanner),也称为旋转扫描仪或圆形扫描仪,是一种用于获取图像和文档的设备,下面就跟随小编一起来学习一下如何使用C++实现旋转扫描仪功能吧
    2024-02-02
  • C++ CopyFile,MoveFile用法案例详解

    C++ CopyFile,MoveFile用法案例详解

    这篇文章主要介绍了C++ CopyFile,MoveFile用法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • C++ Struct结构体用法浅析

    C++ Struct结构体用法浅析

    前边我们所定义的类,均是使用struct关键字来定义,但是C++中真正用于定义类的关键字为class,因为要C++兼容C,所以保留struct关键字,struct与class的用法完全相同
    2023-03-03
  • C++ 构造函数学习笔记

    C++ 构造函数学习笔记

    这篇文章主要为大家介绍了C++ 构造函数学习笔记,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • C++使用map实现多进程拷贝文件的程序思路

    C++使用map实现多进程拷贝文件的程序思路

    这篇文章主要介绍了C++使用mmap实现多进程拷贝文件,通过本文给大家分享程序思路及完整代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • C++ push方法与push_back方法常见方法介绍

    C++ push方法与push_back方法常见方法介绍

    push与push_back是STL中常见的方法,都是向数据结构中添加元素,本文还将简述push对应的stack与queue系列,常见方法的介绍,以及与push_back相对应的vector系列常见方法介绍,感兴趣的朋友跟随小编一起看看吧
    2022-11-11
  • C++类成员函数后面加const问题

    C++类成员函数后面加const问题

    这篇文章主要介绍了C++类成员函数后面加const问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11

最新评论