本文转自:http://blog.sina.com.cn/s/blog_3f7e41390100m0y4.html
./build
|-- CleanSpec.mk
|-- buildspec.mk.default
|-- core
| |--Makefile
| |--apicheck_msg_current.txt
| |--apicheck_msg_last.txt
| |--armelf.x
| |--armelf.xsc
| |--armelflib.x
| |--base_rules.mk
| |--binary.mk
| |--build-system.html
| |--build_id.mk
| |--checktree
| |--cleanbuild.mk
| |--cleanspec.mk
| |--clear_vars.mk
| |--combo
| | |--HOST_darwin-x86.mk
| | |--HOST_linux-x86.mk
| | |--HOST_windows-x86.mk
| | |--TARGET_linux-arm.mk
| | |--TARGET_linux-sh.mk
| | |--TARGET_linux-x86.mk
| | |--arch
| | | `-- arm
| | | |-- armv4t.mk
| | | |-- armv5te-vfp.mk
| | | |-- armv5te.mk
| | | |-- armv7-a-neon.mk
| | | `-- armv7-a.mk
| | |--javac.mk
| | `--select.mk
| |--config.mk
| |--copy_headers.mk
| |--definitions.mk
| |--device.mk
| |--distdir.mk
| |--droiddoc.mk
| |--dynamic_binary.mk
| |--envsetup.mk
| |--executable.mk
| |--filter_symbols.sh
| |--find-jdk-tools-jar.sh
| |--host_executable.mk
| |--host_java_library.mk
| |--host_prebuilt.mk
| |--host_shared_library.mk
| |--host_static_library.mk
| |--java.mk
| |--java_library.mk
| |--key_char_map.mk
| |--main.mk
| |--multi_prebuilt.mk
| |--node_fns.mk
| |--notice_files.mk
| |--package.mk
| |--pathmap.mk
| |--prebuilt.mk
| |--prelink-linux-arm-2G.map
| |--prelink-linux-arm.map
| |--process_wrapper.sh
| |--process_wrapper_gdb.cmds
| |--process_wrapper_gdb.sh
| |--product.mk
| |--product_config.mk
| |--proguard.flags
| |--proguard_tests.flags
| |--raw_executable.mk
| |--raw_static_library.mk
| |--root.mk
| |--shared_library.mk
| |--static_java_library.mk
| |--static_library.mk
| |-- tasks
| | |--apicheck.mk
| | |--cts.mk
| | |--product-graph.mk
| | `--sdk-addon.mk
| `--version_defaults.mk
|-- envsetup.sh
|-- libs
| `-- host
| |-- Android.mk
| |-- CopyFile.c
| |-- include
| | `--host
| | |-- CopyFile.h
| | |-- Directories.h
| | `-- pseudolocalize.h
| |-- list.java
| `-- pseudolocalize.cpp
|-- target
| |-- board
| | |--Android.mk
| | |--emulator
| | | |--AndroidBoard.mk
| | | |--BoardConfig.mk
| | | |--README.txt
| | | |--tuttle2.kcm
| | | `--tuttle2.kl
| | |--generic
| | | |--AndroidBoard.mk
| | | |--BoardConfig.mk
| | | |--README.txt
| | | |--system.prop
| | | |--tuttle2.kcm
| | | `--tuttle2.kl
| | `-- sim
| | |-- AndroidBoard.mk
| | `-- BoardConfig.mk
| `-- product
| |-- AndroidProducts.mk
| |-- core.mk
| |-- full.mk
| |-- generic.mk
| |-- languages_full.mk
| |-- languages_small.mk
| |-- sdk.mk
| |-- security
| | |--README
| | |--media.pk8
| | |--media.x509.pem
| | |--platform.pk8
| | |--platform.x509.pem
| | |--shared.pk8
| | |--shared.x509.pem
| | |--testkey.pk8
| | `--testkey.x509.pem
| `-- sim.mk
² 配置类
主要用来配置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.imgsystem.img update.zip recover.img等。我们可以看看这些img都是如何生成的,对应着我们常用的几个make goals。
在实际的过程中,我们也可以自己编辑out目录下的生成文件,然后手工打包相应生成
相应的img,最常用的是加入一些需要集成进的prebuilt file。所有的Makefile都通过build/core/main.mk这个文件组织在一起,它定义了一个默认goals:droid,当我们在TOP目录下敲Make实际上就等同于我们执行make droid。当Makeinclude所有的文件,完成对所有make文件的解析以后就会寻找生成droid的规则,依次生成它的依赖,直到所有满足的模块被编译好,然后使用相应的工具打包成相应的img。
控制整个android系统编译的make文件。其内容如下:
### DO NOT EDIT THIS FILE###
include build/core/main.mk
### DO NOT EDIT THIS FILE###
可以看出,实际上控制编译的文件是:build/core/main.mk
² make droid:等同于make命令。droid是默认的目标名称。
²
make all: make all将make所有make droid会编译的项目。同时,将编译LOCAL_MODULE_TAGS
定义的不包括
androidtag
的模块。这将确保所有的在代码树里面同时有
Android.mk
文件的模块。
² clean-$(LOCAL_MODULE)和clean-$(LOCAL_PACKAGE_NAME):
删除某个模块的目标文件。例如:clean-libutils将删除所有的libutils.so以及和它相关的中间文件;clean-Home将删除Home应用。
²
makeclean
:删除本次配置所编译输出的结果文件。类似于:
rm –rf ./out/
²
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文件里面应该可以找到。本文不做探讨。
config.mk文件的主要内容如下:
Ø 头文件的定义;(各种include文件夹的设定)
在定义头文件的部分,还include了pathmap.mk,如下:
include$(BUILD_SYSTEM)/pathmap.mk
该文件设置include目录和frameworks/base下子目录等的信息。
Ø 编译系统内部mk文件的定义;
Ø 设定通用的名称;
Ø Include必要的子配置文件;
n buildspec.mk
n envsetup.mk
n BoardConfig.mk
n /combo/select.mk
n /combo/javac.mk
Ø 检查BUILD_ENV_SEQUENCE_NUMBER版本号;
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.
· In config/envsetup.make, incrementthe CORRECT_BUILD_ENV_SEQUENCE_NUMBER definition.
· In buildspec.mk.default, update theBUILD_ENV_SEQUENCE_DUMBER definition to match the one inconfig/envsetup.make
The scripts automatically get thevalue from the build system, so they will trigger the warning aswell.
Ø 设置常用工具的常量;< Generictools.>
Ø 设置目标选项;< Set up finaloptions.>
Ø 遍历并设置SDK版本;
默认情况下,buildspec.mk文件是不存在的,表示使用的多少默认选项。Android只提供了buildspec.mk文件的模板文件build/buildspec.mk.default。如果需要使用buildspec.mk文件,请将该文件拷贝到
buildspec.mk文件主要配置下面的选项:
Ø TARGET_PRODUCT:设置编译之后的目标(产品)类型;
可以设置的值在:build/target/product/中定义。比如,product目录下有下面几个mk文件:
² AndroidProducts.mk
² core.mk
² full.mk
² generic.mk
² languages_full.mk
² languages_small.mk
² sdk.mk
² sim.mk
那么,在这里可以设置的值就为上面几个mk文件的前缀名称(generic等)。
Ø TARGET_BUILD_VARIANT:设置image的类型;
包括三个选项:user、userdebug、eng。
usr: 出厂时候面向用户的image;
userdebug: 打开了一些debug选项的image;
eng: 为了开发而包含了很多工具的image
Ø CUSTOM_MODULES:设置额外的总是会被安装到系统的模块;
这里设置的模块名称采用的是简单目标名,比如:Browser或者MyApp等。这些名字在LOCAL_MODULE或者在LOCAL_PACKAGE_NAME里面定义的。
LOCAL_MODULE
is the name of what's supposed to begenerated from your Android.mk. For exmample, for libkjs,the LOCAL_MODULE
is "libkjs" (the build system addsthe appropriate suffix -- .so .dylib .dll). For app modules,use LOCAL_PACKAGE_NAME
insteadof LOCAL_MODULE
. We're planning on switching to antfor the apps, so this might become moot.
Ø TARGET_SIMULATOR:设置是否要编译成simulator
Ø TARGET_BUILD_TYPE:设置是debug还是release版本
Set this to debug or release if youcare. Otherwise, itdefaults to release for arm and debug for the simulator.
Ø HOST_BUILD_TYPE:设置Host目标是debug版还是release版;
Ø DEBUG_MODULE_ModuleName:配置单个模块的版本是debug还是release;
Ø TARGET_TOOLS_PREFIX:工具名前缀,默认为NULL
Ø HOST_CUSTOM_DEBUG_CFLAGS/TARGET_CUSTOM_DEBUG_CFLAGS:增加额外的编译选项LOCAL_CFLAGS。
LOCAL_CFLAGS:If you have additional flags to pass into the C orC++ compiler, add them here. For example: LOCAL_CFLAGS +=-DLIBUTILS_NATIVE=1
Ø CUSTOM_LOCALES:增加额外的LOCALES到最总的image;
Any locales that appear inCUSTOM_LOCALES but not in the locale list for the selected productwill be added to the end of PRODUCT_LOCALES.
Ø OUT_DIR:编译之后文件保存路径。默认为
Ø ADDITIONAL_BUILD_PROPERTIES:指定(增加)额外的属性文件;
Ø NO_FALLBACK_FONT:设置是否只支持英文(这将减少image的大小)。
Ø WEBCORE_INSTRUMENTATION:webcore支持;
Ø ENABLE_SVG:SVG支持;
Ø BUILD_ENV_SEQUENCE_NUMBER:编译系列号;