Tiny4412 Android 5.0 编译系统学习笔记
1.Android 编译系统概述
②针对某个产品(一个产品可能是某个型号的手机或者平板电脑)的 Make 文件,这些文件通常位于 device 目录下,该目录下又以公司名以及产品名分为两级目录对于一个产品的定义通常需要一组文件,这些文件共同构成了对于这个产品的定义。
③第三类是针对某个模块的 Make 文件。整个系统中,包含了大量的模块,每个模块都有一个专门的 Make 文件,这类文件的名称统一为“Android.mk”,该文件中定义了如何编
译当前模块。Build 系统会在整个源码树中扫描名称为“Android.mk”的文件并根据其中的内容执行模块的编译。
2.编译Tiny4412 Android系统
编译Android系统命令如下:
source build/envsetup.sh lunch full_tiny4412-eng make -j4
build/envsetup.sh
脚本。该脚本的作用是初始化编译环境,并引入一些辅助的 Shell 函数,这其中就包括第二步使用 lunch 函3.源码编译过程分析
整个 Build 系统的入口文件是源码树根目录下的“Makefile”的文件,当在源代码根目录上调用 make 命令时,make 命令首先将读取该文件。它的内容如下。
### DO NOT EDIT THIS FILE ### include build/core/main.mk ### DO NOT EDIT THIS FILE ###
它引用了 build/core/main.mk 文件。 main.mk 文件中又引用了其他.mk文件,其他.mk文件中又会包含更多的.mk文件,这样就将了整个 Build 系统串联起来了。
3.1 主要的 Make 文件的说明
文件名 | 说明 |
---|---|
main.mk | 最主要的 Make 文件,该文件中首先将对编译环境进行检查,同时引入其他的 Make 文件,设置全局变量 和几个最主要的Make目标,比如Droid、sdk等 |
help.mk | 包含了名称为 help 的 Make 目标的定义,该目标将列出主要的 Make 目标及其说明。 |
pathmap.mk | 将许多头文件的路径通过名值对的方式定义为映射表,并提供 include-path-for 函数来获取。例如,通过$(call include-path-for, frameworks-native) 便可以获取到 framework 本地代码需要的头文件路径。 |
envsetup.mk | 配置 Build 系统需要的环境变量,例如:TARGET_PRODUCT,TARGET_BUILD_VARIANT,HOST_OS,HOST_ARCH 等。当前编译的主机平台信息(例如操作系统,CPU 类型等信息)就是在这个文件中确定的。另外,该文件中还指定了各种编译结果的输出路径。 |
combo/select.mk | 根据当前编译器的平台选择平台相关的 Make 文件。 |
dumpvar.mk | 在 Build 开始之前,显示此次 Build 的配置信息。 |
config.mk | 整个 Build 系统的配置文件,最重要的 Make 文件之一。该文件中主要包含以下内容:
|
definitions.mk | 最重要的 Make 文件之一,在其中定义了大量的函数。这些函数都是 Build 系统的其他文件将用到的。例如:my-dir,all-subdir-makefiles,find-subdir-files,sign-package 等,关于这些函数的说明请参见每个函数的代码注释。 |
distdir.mk | 针对 dist 目标的定义。dist 目标用来拷贝文件到指定路径。 |
dex_preopt.mk | 针对启动 jar 包的预先优化。 |
pdk_config.mk | 顾名思义,针对 pdk(Platform Developement Kit)的配置文件。 |
${ONE_SHOT_MAKEFILE} |
ONE_SHOT_MAKEFILE 是一个变量,当使用“mm”编译某个目录下的模块时,此变量的值即为当前指定路径下的 Make 文件的路径。 |
${subdir_makefiles} |
各个模块的 Android.mk 文件的集合,这个集合是通过 Python 脚本扫描得到的。 |
post_clean.mk | 在前一次 Build 的基础上检查当前 Build 的配置,并执行必要清理工作。 |
legacy_prebuilts.mk | 该文件中只定义了 GRANDFATHERED_ALL_PREBUILT 变量。 |
Makefile | 被 main.mk 包含,该文件中的内容是辅助 main.mk 的一些额外内容。 |
3.2 主要Makefile的调用流程
l 初始化相关的参数设置(buildspec.mk、envsetup.mk、config.mk)
l 检测编译环境和目标环境
l 决定目标product
l 读取product的配置信息及目标平台信息
l 清除输出目录
l 检查版本号
l 读取Board的配置
l 读取所有Module的配置
l 根据配置产生必要的规则(build/core/Makefile)
l 生成image
①main.mk:它是整个系统编译系统主导文件,它的主要内容如下
#定义默认的target即make命令后不加参数的默认目标 # This is the default target. It must be the first declared target. .PHONY: droid DEFAULT_GOAL := droid $(DEFAULT_GOAL): #引入help.mk,help.mk 包含了名称为 help 的 Make 目标的定义, #该目标将列出主要的 Make 目标及其说明 # Targets that provide quick help on the build system. include $(BUILD_SYSTEM)/help.mk #引入config.mk,定义产品,主机的各种基本变量 # Set up various standard variables based on configuration # and host information. include $(BUILD_SYSTEM)/config.mk #引入clean操作的定义 # This allows us to force a clean build - included after the config.mk # environment setup is done, but before we generate any dependencies. This # file does the rm -rf inline so the deps which are all done below will # be generated correctly include $(BUILD_SYSTEM)/cleanbuild.mk #引入基本编译系统的定义,提供了大量的实用函数 # Bring in standard build system definitions. include $(BUILD_SYSTEM)/definitions.mk #读取android源码树中所有的Android.mk ifneq ($(dont_bother),true) # # Include all of the makefiles in the system # # Can't use first-makefiles-under here because # --mindepth=2 makes the prunes not work. subdir_makefiles := \ $(shell build/tools/findleaves.py --prune=$(OUT_DIR) --prune=.repo --prune=.git $(subdirs) Android.mk) $(foreach mk, $(subdir_makefiles), $(info including $(mk) ...)$(eval include $(mk)))
②config.mk解析:产品配置主导文件
#引入envsetup.mk定义大部分全局变量,配置编译时的环境变量。 #该文件可以指定用户编译配置 # --------------------------------------------------------------- # Define most of the global variables. These are the ones that # are specific to the user's build configuration. include $(BUILD_SYSTEM)/envsetup.mk
③envsetup.mk:用来配置编译时的环境变量
#引入BoardConfig.mk,BoardConfig.mk主要写了product使用的硬件所支持和不支持的功能性内容。 #BroadConfig.mk设置了每个设备的自己的一些变量值,来区别编译时的行为 include $(board_config_mk) ...... # Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE) # or under vendor/*/$(TARGET_DEVICE). Search in both places, but # make sure only one exists. # Real boards should always be associated with an OEM vendor. board_config_mk := \ $(strip $(wildcard \ $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \ $(shell test -d device && find device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \ $(shell test -d vendor && find vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \ )) #设置版本信息 # Set up version information. include $(BUILD_SYSTEM)/version_defaults.mk #引入产品级别的配置 # Read the product specs so we can get TARGET_DEVICE and other # variables that we need in order to locate the output files. include $(BUILD_SYSTEM)/product_config.mk
④product_config.mk:产品级别的配置,读取指定的目录下所有的AndrodProducts.mk文件中定义的产品信息
#引用AndroidProducts.mk #读取AndrodProducts.mk文件中定义的产品信息 ifneq ($(strip $(TARGET_BUILD_APPS)),) # An unbundled app build needs only the core product makefiles. all_product_configs := $(call get-product-makefiles,\ $(SRC_TARGET_DIR)/product/AndroidProducts.mk) else # Read in all of the product definitions specified by the AndroidProducts.mk # files in the tree. all_product_configs := $(get-all-product-makefiles) endif