本文转自:http://blog.sina.com.cn/s/blog_3f7e41390100m0y4.html
6. 编译详细分解
6.1. build系统简介
6.1.1.build系统文件结构
./build
|-- CleanSpec.mk
|-- buildspec.mk.default
|-- core
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|-- envsetup.sh
|-- libs
|
|
|
|
|
|
|
|
|
|
|-- target
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6.1.2.make文件分类
²
主要用来配置product、board,以及根据你的Host和Target选择相应的工具以及设定相应的通用编译选项:
config文件 | 说明 |
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
除了CLEAR_VARS是清楚本地变量之外,其他所有的都对应了一种模块的生成规则,每一个本地模块最后都会include其中的一种来生成目标模块。大部分上面的.mk都会包含base_rules.mk,这是对模块进行处理的基础文件,建议要写本地模块的都去看看,看明白了为什么Android.mk要这么写就会大致明白了。
²
本地模块的Makefile文件就是我们在Android里面几乎上随处可见的Android.mk。Android进行编译的时候会通过下面的函数来遍历所有子目录中的Android.mk,一旦找到就不会再往层子目录继续寻找(所有你的模块定义的顶层Android.mk必须包含自己定义的子目录中的 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
在实际的过程中,我们也可以自己编辑out目录下的生成文件,然后手工打包相应生成
相应的img,最常用的是加入一些需要集成进的prebuilt file。所有的Makefile都通过build/core/main.mk这个文件组织在一起,它定义了一个默认goals:droid,当我们在TOP目录下敲Make实际上就等同于我们执行make droid。当Makeinclude所有的文件,完成对所有make文件的解析以后就会寻找生成droid的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相应的工具打包成相应的img。
6.2. makefile文件
控制整个android系统编译的make文件。其内容如下:
### DO NOT EDIT THIS FILE###
include build/core/main.mk
### DO NOT EDIT THIS FILE###
可以看出,实际上控制编译的文件是:build/core/main.mk
6.3. Make命令
²
²
make all: LOCAL_MODULE_TAGS
定义的不包括
androidtag
的模块。这将确保所有的在代码树里面同时有
Android.mk
文件的模块。
²
删除某个模块的目标文件。例如:clean-libutils将删除所有的libutils.so以及和它相关的中间文件;clean-Home将删除Home应用。
²
makeclean
:删除本次配置所编译输出的结果文件。类似于:
rm –rf ./out/
<configuration>
²
makeclobber
:删除所有配置所编译输出的结果文件。类似于:
rm –rf ./out/
² makedataclean
:
make dataclean
deletes contents of the datadirectory inside the current combo directory. This is especiallyuseful on the simulator and emulator, where the persistent dataremains present between builds.
²
makeshowcommands
:在编译的时候显示脚本的命令,而不是显示编译的简报。用于调试脚本。
² make
LOCAL_MODULE:编译一个单独得模块(需要有Android.mk文件存在)。
²
maketargets
:将输出所有拟可以编译的模块名称列表。
注:还有一些命令,从make文件里面应该可以找到。本文不做探讨。
6.4. build/core/config.mk
config.mk文件的主要内容如下:
Ø
在定义头文件的部分,还include了pathmap.mk,如下:
include$(BUILD_SYSTEM)/pathmap.mk
该文件设置include目录和frameworks/base下子目录等的信息。
Ø
Ø
Ø
n
n
n
n
n
Ø
In order to make easier for peoplewhen the build system changes, when it is necessary to make changesto buildspec.mk or to rerun the environment setup scripts, theycontain a version number in the variable BUILD_ENV_SEQUENCE_NUMBER.If this variable does not match what the build system expects, itfails printing an error message explaining what happened. If youmake a change that requires an update, you need to update twoplaces so this message will be printed.
·
·
The scripts automatically get thevalue from the build system, so they will trigger the warning aswell.
Ø
Ø
Ø
6.5. buildspec.mk
默认情况下,buildspec.mk文件是不存在的,表示使用的多少默认选项。Android只提供了buildspec.mk文件的模板文件build/buildspec.mk.default。如果需要使用buildspec.mk文件,请将该文件拷贝到<srcDir>根目录下面,并命名为buildspec.mk。同时,需要将模板文件里面的一些必要的配置项启用或者修改为你所需要的目标选项。
buildspec.mk文件主要配置下面的选项:
Ø
可以设置的值在:build/target/product/中定义。比如,product目录下有下面几个mk文件:
²
²
²
²
²
²
²
²
那么,在这里可以设置的值就为上面几个mk文件的前缀名称(generic等)。
Ø
包括三个选项:user、userdebug、eng。
usr:
userdebug:
eng:
Ø
这里设置的模块名称采用的是简单目标名,比如:Browser或者MyApp等。这些名字在LOCAL_MODULE或者在LOCAL_PACKAGE_NAME里面定义的。
LOCAL_MODULE
LOCAL_MODULE
LOCAL_PACKAGE_NAME
LOCAL_MODULE
. We're planning on switching to antfor the apps, so this might become moot.
Ø
Ø
Set this to debug or release if youcare.
Ø
<release or debug,default is debug>
Ø
Ø
Ø
LOCAL_CFLAGS:If you have additional flags to pass into the C orC++ compiler, add them here. For example: LOCAL_CFLAGS +=-DLIBUTILS_NATIVE=1
Ø
Any locales that appear inCUSTOM_LOCALES but not in the locale list for the selected productwill be added to the end of PRODUCT_LOCALES.
Ø
Ø
Ø
Ø
Ø
Ø