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_MK=true来打开快速编译的功能,由于没有对错误进行检测的操做,因此使用的时候必定要特别当心。java
每一个应用模块都会有个Android.mk文件,在这个文件里都会定义LOCAL_MODULE_TAGS和LOCAL_PACKAGE_NAME,若是想把这个应用编译进去的话,就须要在generic.mk里面的PRODUCT这个变量后面加上这个应用的 LOCAL_PACKAGE_NAME,LOCAL_MODULE_TAGS通常是user ,debug,eng这几个选择一个
举个例子:PRODUCT+=Music // LOCAL_PACKAGE_NAMEshell