zoukankan      html  css  js  c++  java
  • Android Makefile and build system 分析与梳理

    Android Makefile and build system 分析与梳理

    前言:预计未来一致两年内移动互联网将会有很大的发展,必将孕育很多的机会,而Google 推出的Android 手机操作系统无疑将是移动互联网中的明星。由于其是开源系统,很有必要对此进行深入研究。
             工欲善其事,必先利其器。Makefile无疑是打开系统架构的一扇窗户。但因Android的Makefile (build system)文件众多,架构复杂,分析起来较为困难。本文梳理了build system的大致脉络,希望对build system感兴趣的同学们有所帮助。

    1.        Android Makefile & build system 概述
             Makefile文件用来告诉make命令需要怎么样的去编译和链接程序。在编译时,需要根据编译环境和编译目标选择编译工具,编译参数,以及选择编译安装哪些模块。同时Makefile 指定了构建目标所需的依赖性以及生成规则。 在Android中,主要的Makefile文件存在于build/core/目录下,它的表现形式为多个后缀为mk的文件组成,也称为build system。Android build system 主要有两大部分构成:配置部分,目标构建部分。Build system的主流程文件为build/core/main.mk文件。
            Android build system在设计中考虑了如下方面,具有良好的扩展性。
    a)        增添子模块编译
    b)        多CPU架构 –  ARM/PPC(maybe)/X86(maybe)
    c)        多语言编译 – C/C++/Java
    d)        多目标 – static lib/share lib/execute/Java/Java library
    e)        多发布版本
           本文也将就围绕这些特性做进一步分析。

    2.          Build system 配置部分
            配置部分主要完成以下几个工作:
    a)        基于Android 产品的配置(product config):选择构建安装的运行程序 (user package)
    b)        设置target 等相关变量TARGET_ARCH, TARGET_OS, TARGET_BUILD_TYPE, TARGET_PREBUILT_TAG
    c)        根据编译环境设置host等相关变量 HOST_OS, HOST_ARCH, HOST_BUILD_TYPE, HOST_PREBUILT_TAG
    d)        编译target上运行程序所需的工具链及编译参数设置,如linux-arm-cc,cflag,include目录等。
    e)        编译host上运行程序所需的工具链及编译参数设置。


            下图简要介绍了Android build system的配置部分的主要构成及相互关系。


    多发布版本的支持

            Android 会被不同的厂商所采用,他们内置的packages(应用程序)相应也会有差别。AndroidProducts.mk文件即为Android build system提供给厂商的接口文件。通过此文件即可定义所需编译和安装的packages(也即应用程序)。缺省选项是generic。为了更容易的扩展,Android定义了基本package(core.mk)和通用package(generic.mk),通用package包含基本package。同时Android还实现了一个继承函数(inherit-product)。通过继承通用package,可以很容易的配置所需编译和安装的package。

    多CPU架构的扩展
            Config.mk文件中会设置combo_target为不同的变量,然后include select.mk文件。在select.mk文件中,会根据OS和CPU架构选择相应的mk文件,在这些相应的mk文件中,又定义了编译目标程序所需的工具链及编译参数。目前从combo目录下看,target上不支持PPC架构。但如果要想支持PPC架构的话,只需在combo目录下创建PPC的mk文件,在其中定义工具链和参数即可。



    3.         build system 目标构建部分

            目标构建部分的主要工作就是选择所需构建的目标,确定它们所需依赖的目标,然后根据规则来构建最终的目标。说起来简单,可是在实际中就需要考虑很多问题了。
    a) 作为一个设计优秀的Framework,如何方便的添加子模块?
    b) 在Android系统中,有多种编程语言的存在,它们的编译工具各不相同。即使同一种语言,如C语言,也存在host 和target的差别,编译器也不同。如何选择不同的工具进行模块的构建?
    c) 在Android系统中,存在不同种类的构建目标:有可执行文件,static library, dynamic library,java library,java。如何构建这些不同的目标?


          下图简要介绍了Android build system的构建部分的主要构成及相互关系



            在main.mk中,非常关键的一个步骤就是找到TOP目录下所有Android.mk文件,并include 它们。在Include的过程中,就会确定子模块的构建目标,类型,和规则。
            Android.mk就是build system提供给子模块的借口文件。Android.mk有下面几个关键词:
    LOCAL_SRC_FILES – 指定模块的源文件
    LOCAL_MODULE – 指定所需构建的目标名
    include 构建类型对应的文件 – 例如想构建在target上运行的可执行文件,那就执行语句include $(BUILD_EXECUTABLE)。通过此语句可有如下结果:a) 指定构建目标的类型 b)确定构建此类型所需的工具及参数。
            通过定义自己的Android.mk文件,再修改上述等变量,即可轻松的把自身模块放入至build system中。

            Main.mk 文件471行: include $(subdir_makefiles)
            subdir_makefiles为TOP目录下所有Android.mk文件的集合。语句虽短,可确是整个build system中最为重要的一条语句。无论有多少子模块,无论构建模块的目标类型,无论它是什么语言所写,就这一条语句,完成了这些纷繁复杂的工作。

            是否似曾相识?Android.mk 就类似于build system提供的基类,LOCAL_MODULE,LOCAL_SRC_FILES,include构建类型文件等类似于基类提供的虚函数。通过继承基类(Android.mk),重写虚函数(重新定义LOCAL_等变量),遍历子类集合调用虚函数(include $(subdir_makefiles)),完美的解决了本节开头的问题。为Android build system提供了良好的可扩展性。

    后记:
            设计模式,架构并不仅存于OO的语言中(Java/C++)。即便如Makefile的类脚本语言,也可写出如此之架构。设计的思想在于人,而不取决于他所用的工具。

  • 相关阅读:
    钱多多软件制作04
    团队项目01应用场景
    HDU 4411 arrest
    HDU 4406 GPA
    HDU 3315 My Brute
    HDU 3667 Transportation
    HDU 2676 Matrix
    欧拉回路三水题 POJ 1041 POJ 2230 POJ 1386
    SPOJ 371 BOXES
    POJ 3422 Kaka's Matrix Travels
  • 原文地址:https://www.cnblogs.com/rollrock/p/2097316.html
Copyright © 2011-2022 走看看