Tiny4412 Android 5.0 编译系统学习笔记

1.Android 编译系统概述

Build 系统中最主要的处理逻辑都在 Make 文件中,而其他的脚本文件只是起到一些辅助作用。

整个 Build 系统中的 Make 文件可以分为三类:

① Build 系统核心文件,此类文件定义了整个 Build 系统的框架,而其他所有 Make 文件都是在这个框架的基础上编写出来的。Build 系统核心文件全部位于 /build/core目录下。

②针对某个产品(一个产品可能是某个型号的手机或者平板电脑)的 Make 文件,这些文件通常位于 device 目录下,该目录下又以公司名以及产品名分为两级目录对于一个产品的定义通常需要一组文件,这些文件共同构成了对于这个产品的定义。

③第三类是针对某个模块的 Make 文件。整个系统中,包含了大量的模块,每个模块都有一个专门的 Make 文件,这类文件的名称统一为“Android.mk”,该文件中定义了如何编

译当前模块。Build 系统会在整个源码树中扫描名称为“Android.mk”的文件并根据其中的内容执行模块的编译

2.编译Tiny4412 Android系统

编译Android系统命令如下:

source build/envsetup.sh
lunch full_tiny4412-eng
make -j4

①第一行命令“source build/envsetup.sh”引入了 build/envsetup.sh脚本。该脚本的作用是初始化编译环境,并引入一些辅助的 Shell 函数,这其中就包括第二步使用 lunch 函

数。它还会引入device/company/product/vendorsetup.sh

②第二行命令“lunch full-eng”是调用 lunch 函数,并指定参数为full_tiny4412-eng。lunch 函数的参数用来指定此次编译的目标设备以及编译类型。调用lunch函数

首先执行add_lunch_combo()函数 这样就显示一个列表,当你选择后 系统会调用choosecombo()后 会预先设置值一些环境变量 并且调用config.mk ,

所有跟config.mk有关的后面的步骤都是这个时候执行的。命令行也可以看到一系列的环境变量显示,实现该命令是 dumpvar.mk。

③调用make 执行make droidcore ,主要提取了Android.mk的定义规则 并找到整个系统有关该文件的脚本 做一个系统级的编译。

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 文件之一。该文件中主要包含以下内容:

  • 定义了许多的常量来负责不同类型模块的编译。
  • 定义编译器参数以及常见文件后缀,例如 .zip,.jar.apk。
  • 根据 BoardConfig.mk 文件,配置产品相关的参数。
  • 设置一些常用工具的路径,例如 flex,e2fsck,dx。
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的调用流程

build/core/main.mk主要流程为:

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

⑤AndroidProducts.mk

列出了产品版本定义文件名的列表 该列表下的文件定义了产品的各种版本信息

⑥BoardConfig.mk

该文件用来配置产品,它其中定义的都是设备底层的硬件特性,例如该设备的板级相关信息,Wifi相关信息以及bootloader和内核等信息。

参考文章:

http://www.ibm.com/developerworks/cn/opensource/os-cn-android-build/

http://www.jianshu.com/p/6d0e3492c91e

时间: 2024-08-16 02:12:39

Tiny4412 Android 5.0 编译系统学习笔记的相关文章

Android(java)学习笔记167:Java中操作文件的类介绍

1.File类:对硬盘上的文件和目录进行操作的类.    File类是文件和目录路径名抽象表现形式  构造函数:        1) File(String pathname)       Creates a new File instance by converting the given pathname string into an abstract pathname. 2)File(File parent, String child)       Creates a new File i

Android(java)学习笔记205:网易新闻客户端应用编写逻辑过程

1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,blog和wiki,主要的版本有0.91, 1.0, 2.0.使用RSS订阅能更快地获取信息,网站提供RSS输出,有利于让用户获取网站内容的最新更新.网络用户可以在客户端借助于支持RSS的聚合工具软件,在不打开网站内容页面的情况下阅读支持RSS输出的网站内容. 例如如下的网易RSS订阅: 2.由于我们这

Android(java)学习笔记204:自定义SmartImageView(继承自ImageView,扩展功能为自动获取网络路径图片)

1.有时候Android系统配置的UI控件,不能满足我们的需求,Android开发做到了一定程度,多少都会用到自定义控件,一方面是更加灵活,另一方面在大数据量的情况下自定义控件的效率比写布局文件更高. 2.下面我们是自定义一个SmartImageView继承自ImageView,扩展了ImageView的功能:     步骤: • 新建一个SmartImageView类,让继承自ImageView(放置特定的包下): • 实现SmartImageView类下的构造方法,最好全部实现,这个不容易出

Android(java)学习笔记233: 远程服务的应用场景(移动支付案例)

一. 移动支付:       用户需要在移动终端提交账号.密码以及金额等数据 到 远端服务器.然后远端服务器匹配这些信息,进行逻辑判断,进而完成交易,返回交易成功或失败的信息给移动终端.用户提交账号.密码以及金额等数据都是比较敏感的数据,这些数据不能让外界获取.       阿里等等支付宝平台把支付的逻辑封装起来,只给我们提供一个方法去调用,这样提高了安全性.当我们用户提交账号.密码以及金额等数据,点击"支付"的时候,支付宝平台已经调用方法加密数据(这个支付逻辑是远程服务,为了安全,防

Android(java)学习笔记160:Framework运行环境之启动Zygote

前面Android(java)学习笔记159提到Dalvik虚拟机启动初始化过程,就下来就是启动zygote进程: zygote进程是所有APK应用进程的父进程:每当执行一个Android应用程序,Zygote就会孵化一个子线程去执行该应用程序(系统内部执行dvz指令完成的)  Å特别注意:系统提供了一个app_process进程,它会自动启动ZygoteInit.java和SystemServer.java这两个类,app_process进程本质上是使用dalvikvm启动ZygoteInit

Android(java)学习笔记71:生产者和消费者之等待唤醒机制

首先我们根据梳理我们之前Android(java)学习笔记70中关于生产者和消费者程序思路: 下面我们就要重点介绍这个等待唤醒机制: 第一步:还是先通过代码体现出等待唤醒机制 package cn.itcast_05; /* * 分析: * 资源类:Student * 设置学生数据:SetThread(生产者) * 获取学生数据:GetThread(消费者) * 测试类:StudentDemo * * 问题1:按照思路写代码,发现数据每次都是:null---0 * 原因:我们在每个线程中都创建了

Android(java)学习笔记179:有序广播和无序广播

之前我们在Android(java)学习笔记178中自定义的广播是无序广播,下面我们要了解一下有序广播:   1.   我们首先了解一下有序广播和无序广播区别和联系? (1) 有序广播> 接受者有优先级,接受按照先后顺序接受,类似中央向下传文件.高优先级的接受者可以把广播消息给拦截,还可以修改广播的数据.(2)无序广播> 接受者没有优先级,没有先后顺序.类似听广播,看新闻联播.不可以被拦截.> sendBroadcast(intent) (3).有序广播和无序广播没有什么本质的区别,相同

HBase-1.0.1学习笔记汇总

欢迎访问:鲁春利的工作笔记,学习是一种信仰,让时间考验坚持的力量. HBase-1.0.1学习笔记(一)集群搭建 http://luchunli.blog.51cto.com/2368057/1682049HBase-1.0.1学习笔记(二)客户端访问 http://luchunli.blog.51cto.com/2368057/1687458 HBase-1.0.1学习笔记(三)启动脚本解析 http://luchunli.blog.51cto.com/2368057/1690619 HBas

[转载]Android Bitmap和Canvas学习笔记

http://blog.chinaunix.net/uid-20771867-id-3053339.html [转载]Android Bitmap和Canvas学习笔记,布布扣,bubuko.com