Android Building System 总结

Android 以模块的形式来组织各个系统中的部件, Eng 专业点的词汇就是 Module ,就是各位在几乎每个目录下都
能看到的 Android.mk 。可以简单地把 Android 所有的 Make 文件分为 4 种:
      1
For config
      
这类文件主要来配置 product board ,以及根据你的 Host Target 选择相应的工具以及设定相应的通用编译选项:
     build/core/config.mk         summary ofconfig
      build/core/envsetup.mk   generate dir config and so on
     build/target/product         productconfig
     build/target/board           board config
     build/core/combo             build flags config
      
这里解释下这里的 board product borad 主要是设计到硬件芯片的配置,比如是否提供硬件的某些功能,比如说 GPU 等等,或者芯片支持浮点
运算等等。 product 是指针对当前的芯片配置定义你将要生产产品的个性配置,主要是指 APK 方面的配置,哪些 APK 会包含在哪个 product 中,哪
APK 在当前 product 中是不提供的。
      config.mk
是一个总括性的东西,它里面定义了各种 module 编译所需要使用的 HOST 工具以及如何来编译各种模块,比如说 BUILT_PREBUILT 就定义了如何来编译预编译模块。 envsetup.mk 主要会读取由 envsetup.sh 写入环境变量中的一些变量来配置
编译过程中的输出目录, combo 里面主要定义了各种 Host Target 结合的编译器和编译选项。
      2
Module Compile
      
这类文件主要定义了如何来处理 Module Android.mk ,以及采用何种方式来生成目标模块,这些模块生成规则都定义在 config.mk 里面,
我们可以看看:
      CLEAR_VARS:= $(BUILD_SYSTEM)/clear_vars.mk
      BUILD_HOST_STATIC_LIBRARY:=$(BUILD_SYSTEM)/host_static_library.mk
      BUILD_HOST_SHARED_LIBRARY:=$(BUILD_SYSTEM)/host_shared_library.mk
      BUILD_STATIC_LIBRARY:=$(BUILD_SYSTEM)/static_library.mk
      BUILD_RAW_STATIC_LIBRARY :=$(BUILD_SYSTEM)/raw_static_library.mk
      BUILD_SHARED_LIBRARY:=$(BUILD_SYSTEM)/shared_library.mk
      BUILD_EXECUTABLE:= $(BUILD_SYSTEM)/executable.mk
      BUILD_RAW_EXECUTABLE:=$(BUILD_SYSTEM)/raw_executable.mk
      BUILD_HOST_EXECUTABLE:=$(BUILD_SYSTEM)/host_executable.mk
      BUILD_PACKAGE:= $(BUILD_SYSTEM)/package.mk
      BUILD_HOST_PREBUILT:=$(BUILD_SYSTEM)/host_prebuilt.mk
      BUILD_PREBUILT:= $(BUILD_SYSTEM)/prebuilt.mk
      BUILD_MULTI_PREBUILT:=$(BUILD_SYSTEM)/multi_prebuilt.mk
      BUILD_JAVA_LIBRARY:= $(BUILD_SYSTEM)/java_library.mk
      BUILD_STATIC_JAVA_LIBRARY:=$(BUILD_SYSTEM)/static_java_library.mk
      BUILD_HOST_JAVA_LIBRARY:=$(BUILD_SYSTEM)/host_java_library.mk
      BUILD_DROIDDOC:= $(BUILD_SYSTEM)/droiddoc.mk
      BUILD_COPY_HEADERS := $(BUILD_SYSTEM)/copy_headers.mk
      BUILD_KEY_CHAR_MAP :=$(BUILD_SYSTEM)/key_char_map.mk
      
除了 CLEAR_VARS 是清楚本地变量之外,其他所有的都对应了一种模块的生成规则,每一个本地模块最后都会 include 其中的一种来生成目标模块。
大部分上面的 .mk 都会包含 base_rules.mk ,这是对模块进行处理的基础文件,建议要写本地模块的都去看看,看明白了为什么 Android.mk 要这么写就会大致明白了。
      3
Local Module
      
本地模块的 Makefile 文件就是我们在 Android 里面几乎上随处可见的 Android.mk Android 进行编译的时候会通过下面的函数来遍
历所有子目录中的 Android.mk ,一旦找到就不会再往层子目录继续寻找 ( 所有你的模块定义的顶层 Android.mk 必须包含自己定义的子目录中的 Android.mk)
      subdir_makefiles += \
          $(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
      
不同类型的本地模块具有不同的语法,但基本上是相通的,只有个别变量的不同,如何添加模块在前面的帖子已经说过了,大家可以参考。
       Android
通过 LOCAL_MODULE_TAGS 来决定哪些本地模块会不会编译进系统,通过 PRODUCT LOCAL_MODULE_TAGS
决定哪些应用包会编译进系统,如果用户不指定 LOCAL_MODULE_TAGS ,默认它的值是 user 。此外用户可以通过 buildspec.mk 来指
定你需要编译进系统的模块。
用户也可以通过 mm 来编译指定模块,或者通过 make clean-module_name 来删除指定模块。
       4
Package
      
这主要指的是 build/core/Makefile 这个文件,它定义了生成各种 img 的方式,包括 ramdisk.img   userdata.img system.img  update.zip  recover.img 等。我们可以看看这些 img 都是如何生成的,对应着我们常用的几个 make goals.
在实际的过程中,我们也可以自己编辑 out 目录下的生成文件,然后手工打包相应生成
相应的 img ,最常用的是加入一些需要集成进的 prebuilt file
所有的 Makefile 都通过 build/core/main.mk 这个文件组织在一起,它定义了一个默认 goals droid ,当我们在 TOP 目录下
Make 实际上就等同于我们执行 make droid 。当 Make include 所有的文件,完成对所有 make 我文件的解析以后就会寻找生成 droid 的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用
相应的工具打包成相应的 img

基本上 Android building system 就是以这样一种方式组织在一起的了,下面说一点闲散的东西。首先是如何来加快 Android 的编译过程,因为每次 Android 都要遍历所有
Android.mk ,不管是编译整个工程还是只编译某个模块。所以可以将遍历的结果保存下来,下次直接从文件读就好了,但是这里容易出错,所以一定要
确认是否正确包含了所有的 .mk ,当新加入文件的时候确认将原来保存的文件删除。下面是我写的加快编译的一个 makefile ,将下面的语句替换掉 main.mk 中的相应部分就可以了:
       FROM

       subdir_makefiles += \
           $(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
       TO

       ifneq ($(ONE_SHOT_MAKEFILE),)
       else
       ifneq ($(CASH_MK),true)
       subdir_makefiles += \
           $(shell build/tools/findleaves.sh--prune="./out" $(subdirs) Android.mk)
      else
     subdir-makefiles-cash := $(shell catbuild/subdir_mk_cash)
     ifeq ($(subdir-makefiles-cash),)
     $(warning No .mk cash ,create now !)
     subdir_makefiles += \
           $(shellbuild/tools/findleaves.sh --prune="./out" $(subdirs) Android.mk)
     mk-to-file := $(shell echo $(subdir_makefiles) >build/subdir_mk_cash)
     else
    $(warning Using cash mk !)
    subdir_makefiles := $(shell cat build/subdir_mk_cash)
    endif
    endif
    endif

       通过CASH_MKtrue来打开快速编译的功能,因为没有对错误进行检测的操作,所以使用的时候一定要特别小心。

每个应用模块都会有个Android.mk文件,在这个文件里都会定义LOCAL_MODULE_TAGS和LOCAL_PACKAGE_NAME,如果想把这个应用编译进去的话,就需要在generic.mk里面的PRODUCT这个变量后面加上这个应用的 LOCAL_PACKAGE_NAME,LOCAL_MODULE_TAGS一般是user ,debug,eng这几个选择一个
举个例子:PRODUCT+=Music   // LOCAL_PACKAGE_NAME

你可能感兴趣的:(Android Building System 总结)