注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

东东的博客

江南烟雨,同大家一起分享

 
 
 

日志

 
 

Android平台开发 -Android build system-编译系统分析  

2012-06-06 10:28:06|  分类: android相关 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

一、预习Makefile
        二、Android编译系统的层次
        三、Android编译系统的常用配置文件
        四、Android编译系统的流程
        五、Android编译系统的使用



一、预习Makefile
Makefile的规则:
target ... : prerequisites ...
command
...
...
target也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。
prerequisites就是,要生成那个target所需要的文件或是目标。
command也就是make需要执行的命令。(任意的Shell命令)
这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,
其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文
件要新的话,command所定义的命令就会被执行。这就是 Makefile的规则。也就是Makefile中最核心的
内容。正如上面作者所述,上面是Makefile中最核心的内容,Android编译系统符合GNU make的标准,
当然这 也是Android 编译系统最核心的内容。

二、Android编译系统的层次
Android编译系统(build system)集中于Android源码下的build/core下,在Android2.2中,共有
56个*.mk文件。另外还有一些shell脚本。Android编译系统完成的并不仅仅是对目标(主机)系统二进
制文件、java应用程序的编译、链接、打包等,而且还有包括生成各种依赖关系、确保某个模块的修改引起
相依赖的文件的重新编译链接,甚至还包括目标文件系统的生成,配置文件的生成等,因此Android编译系
统具有支持多架构(linux-x86、windows、arm等)、多语言(汇编、C、C++、Java等)、多目标、多
编译方式。

编译层次包含了下表描述的抽象层。每一层都与一个或多个层相关联。例如,一个arch有多个 board,每个
board有多个device。你可以在一个层中定义一个元素,以达到排除复制,简化维护的目的。


Layer                                                    Example                                                                                  Description


Product                                      myProduct, myProduct_eu, j2, sdk                                                 产品层定义完整的移植产品的语法。
                                                    myProduct_eu_fr,                                                                             定义要编译哪些模块,怎么配置。基于区域
                                                                                                                                                               或者基于特性,比如照相机,你可能要提供几
                                                                                                                                                               个不同的版本。


Device                                        myDevice, myDevice_eu,                                                               设备层代表设备的物理层。例如,北美设备可
                                                    myDevice_eu_lite                                                                            能包含QWERTY键盘,而在法国售卖的设备可能
                                                                                                                                                               包含AZERTY键盘。外围设备一般与设备层连接

Board                                          sardine, trout, goldfish                                                                     电路板层代表产品的原始图。可能还有外围设备
                                                                                                                                                                连接到这一层。


Arch                                           arm (arm5te) (arm6), x86, 68k                                                         体系层描述了在电路版上运行的处理器。

三、Android编译系统的常用配置文件

在Android中,主要的Makefile文件存在于build/core/目录下,它的表现形式为多个后缀为mk的文件组
成,也称为build system。Android build system 主要有两大部分构成:配置部分,目标构建部分。
Build system的主流程文件为build/core/main.mk文件。
几个很重要的*.mk文件如下:

buildspec.mk:位于根目录下,可在此选择要产生的product 、平台、额外的module/package等。
build/buildspec.mk.default是样板。
AndroidProducts.mk:即为Android build system提供给厂商的接口文件。通过此文件即可定义所需编译和安装的packages(也即应用程序)。缺省选项是generic。
BoardConfig.mk:是为product主板做设定,例如driver选择设定,选择CPU架构等等。
Android.mk:是 module 和 package 的设置文件,每个 module/package 的目录下都会有一个
Android.mk。所谓的 module 是指系统的 native code ,相对于用 Java写成的
Androidapplication 称为 package。
Build/envsetup.mk:编译环境初始化,定义一些实用的shell函数,方便编译使用。
build/core/Makefile:包含build/core /main.mk,此文件主要控制生成
system.img,ramdisk.img,userdata.img,以及recorvery image,sdk等。
main.mk:实际的主控Makefile,例如找到TOP目录下所有Android.mk文件。
config.mk:定义了编译目标程序所需的工具链及编译参数。
base_rules.mk:对一些Makefile的变量规则化
Binary.mk:控制如何生成目标文件
Clear_vars.mk:清除编译系统中用到的临时变量
definations.mk:定义了很多编译系统中用到的宏,相当于函数库
Copy_headers.mk:将头文件拷贝到指定目录
Combo/linux-arm.mk:控制如何生成linux-arm二进制文件,包括ARM相关的编译器,编译参数等的设置
build/envsetup.sh:提供了几个有用的命令,执行 . build/envsetup.sh(.后面有空格)。

注:其中对模块编译有帮助的是tapas、m、mm、mmm这几个命令。

1、tapas——以交互方式设置build环境变量。
输入:tapas
第一步,选择目标设备:
例如我们选择1
第二步,选择代码格式:
我们选择1
第三步,选择产品平台:
注意:这里,Google源代码里默认是 generic。

2、m、mm、mmm使用独立模块的make命令
m 从根目录开始编译;
mm 编译当前目录下的所有模块;
mmm 编译指定目录下的所有模块;

四、 Android编译系统的流程

主要流程都是由 build/core/main.mk 所安排的。
1、初始化相关变量
2、检测编译环境和目标环境
3、决定目标product
4、读取 product 的设定
5、读取 product 所指定之目标平台架构设定
6、选择 toolchain
7、指定编译参数 (*-.mk)
8、清除输出目录
9、设定/检查版本编号
10、读取所有 BoardConfig.mk 文件
11、读取所有 module 的设定
12、根据设定,产生必需的 rule
13、产生 image

1、 初始化和检测

由 build/core/config.mk 进行。 build/core/envsetup.mk 检查 developer 的设定
(buildspec.mk),并检查执行环境,以决定输出目录和环境。build/core/config.mk 本身还依据
参数,决定解释时的相关参数,例如 compiler 的路径、flags, lex 、yacc 的路径参数等。关于
product的相关设定,则是由build/core/product_config.mk 所处理,使用
build/core/product.mk提供之 macro 载入。根据 AndroidProduct.mk 的內容,
product_config.mk 决定了:PRODUCT_TAGS,OTA_PUBLIC_KEYS,PRODUCT_POLICY等。

2、Product 设定的读取
Android product 的设定来自于build/target/product/AndroidProduct.mk 和 vendor 子目
录下AndroidProduct.mk 。building system透过 find 指令,找出所有可能的
AndroidProduct.mk。AndroidProduct.mk里定义PRODUCT_MAKEFILES变量,列举所有实际定义
product的 makefile。这些makefile 各自定义独立的 product。product 相关参数,存成
PRODUCTS. . 形式的变量。并将makefile 路径存在 PRODUCTS 变量。因此,透过 PRODUCTS 能取
得所有的 product 路径/名称,并透过 PRODUCTS. . 形式的变量取得內容。

3、 Module 设定的读取
Module 是指 native code 的软件模块,而 Java application 則被称为 package。
build/core/definitions.mk 定义module/package 相关 macro ,读取、检查
module/package 定义档;分散 source tree 各处的 Android.mk 文件。
build/core/main.mk 使用 find 指令,在这些子目录下找出所有 Android.mk ,并将路径存在
subdir_makefiles 变量里。最后,include 这些文件。这些Android.mk 会 include 定义成变量
BUILD_SHARED_LIBRARY 、BUILD_PACKAGE 等,和其目的相配的 makefile。这些 makefile 会
变 Android.mk 定义之內容,存成 ALL_MODULES. Android.mk>. 的形式。例如,Android.mk 定
义了LOCAL_MODULE_SUFFIX ,会变存成 ALL_MODULES.
Android.mk>.LOCAL_MODULE_SUFFIX 。而 Android.mk 路径,同样会存于ALL_MODULES 变量
里。查找 Android.mk 的路径,基本上会是整个 source tree 。但会依特定的 goal , 选择性只
找寻特定目录。例如 SDK 只需特定目录下的 Android.mk 。

4、Board Level 设定
和目标平台主板相关之设定,例如使用了什么装置、driver 等,或是是否需要编译bootloader 、
kernel等,都是在 BoardConfig.mk 里设定。同样,每张主板可以有不同设定,存在不同目录下的
BoardConfig.mk,以 find 寻找如下文件:
build/target/board/$(TARGET_DEVICE)/BoardConfig.mk
device$(TARGET_DEVICE)/BoardConfig.mk
TARGET_DEVICE 是 product 所定义,因此同一个 BoardConfig.mk 可被多个 product 所使用。
一个 TARGET_DEVICE ,通常只有一个 BoardConfig.mk 。 BoardConfig.mk 会被直接
include 到 building system 的 name space 里。 因此,一些 module 的
enable/disable ,可以在 BoardConfig.mk 以对应不同的主板。

5、Rules
在 module 的定义文件 Android.mk 裡,可定义 module 的 tag, LOCAL_MODULE_TAGS,以分
类这些 module。每一个 product 可以指定需要的 tag (PRODUCT_TAGS),使 building system
只便宜标示这些 tag 的 module。在 build/core/main.mk 里,所有标示特定 tag 的 module 收
集为 ALL_DEFAULT_INSTALLED_MODULES,并 include build/core/Makefile 处理。
build/core/Makefile 为这些 module 产生 rule ,并使产生 image 的 goal depend on 这
些 rule ,使这些 module 被编译。

五、Android编译系统的使用

下面两种方法,第一个产生更稳定的结果。

方法一:
创建buildspec.mk的本地版本。最容易的方法是进入你的设备目录,
执行下列指令:
cp buildspec.mk.default buildspec.mk ; chmod u=rw buildspec.mk

默认的buildspec.mk文件,所有的选项都是被注释的,为了建立个性化的配置环境,可以编辑
buildspec.mk.
一般设置如下选项就可以拉:
BUILD_ENV_SEQUENCE_NUMBER := 9
TARGET_BOARD_PLATFORM := imx53
TARGET_PRODUCT := mine_mx53
一旦建立了配置文件,然后复制到根目录下,就能够通过执行make编译设备代码,在第一次执行这个命令
的时候,会花费很长时间,在双核机器上,考虑使用’-j2’(甚至’j4’)以加速编译。
make -j2

方法二:
做一个通用的版本,
执行
source //device/envsetup.sh, 这个文件包含了必要的变量和函数定义,下面有描述:
cd $TOP
.envsetup.sh
partner_setup generic //select generic as the product
make -j4 PRODUCT-generic-user

//你也可以用eng替换user, 生成一个调式版。
make -j4 PRODUCT-generic-eng

转自:http://keyewan.blog.163.com/blog/static/18982723320111050259815/

  评论这张
 
阅读(1054)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017