² 配置类
主要用来配置product 、board ,以及根据你的Host 和Target 选择相应的工具以及设定相应的通用编译选项:
config 文件 |
说明 |
build/core/config.mk |
Config 文件的概括性配置 |
build/core/envsetup.mk |
generate 目录构成等配置 |
build/target/product |
产品相关的配置 |
build/target/board |
硬件相关的配置 |
build/core/combo |
编译选项配置 |
这里解释下这里的board 和product 。board 主要是设计到硬件芯片的配置,比如是否提供硬件的某些功能,比如说GPU 等等,或者芯片支持浮点运算等等。product 是指针对当前的芯片配置定义你将要生产产品的个性配置,主要是指APK 方面的配置,哪些APK 会包含在哪个product 中,哪些APK 在当前product 中是不提供的。
config.mk 是一个总括性的东西,它里面定义了各种module 编译所需要使用的HOST 工具以及如何来编译各种模块,比如说 BUILT_PREBUILT 就定义了如何来编译预编译模块。envsetup.mk 主要会读取由envsetup.sh 写入环境变量中的一些变量来配置编译过程中的输出目录,combo 里面主要定义了各种Host 和Target 结合的编译器和编译选项。
² 模块组织类
这类文件主要定义了如何来处理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 要这么写就会大致明白了。
² 单个模块编译类
本地模块的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 来删除指定模块。
² 系统生成类
这主要指的是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 。