Android Building System 分析

Android Building System 分析
by thinker
关键字: 
想要了解一个系统,我常会从makefile或是building system下手,以了解系统组成元素为何?目录结构为何?对于 Android ,我也不例外。透过了解building system ,我们能知道如何新增、修改、删除程式,并保有完整性,顺利编译出结果。

设定档

Android building system包括几种重要的设定档,

  • Android .mk
  • AndroidProducts.mk
  • target_<os>-.mk, host_-.mk and -.mk
  • BoardConfig.mk
  • buildspec.mk

Android .mk是module和package的设定档,每个module/package的目录下都会有一个Android.mk。所谓的module是指系统的native code ,相对于用Java写成的Android application称为package。

AndroidProducts.mk 则设定product 配置。product 即特定系统版本,透过编译不同product ,产生不同软体配置内容,安装不同的application。Product 可视为特定专案,产生特定规格系统。

BoardConfig.mk 是为product 主板做设定,像是driver 选择、 设定。*-.mk 则是针对选择的作业系统和CPU 架构,进行相关设定。

buildspec.mk 是位于source 根目录下,为进行编译者所做之额外设定。例如,可在此选择要产生的product 、平台、额外的module/package 等。

参数

build/envsetup.sh实作一个mm指令,以编译单一module,不需编译整个source tree。ONE_SHOT_MAKEFILE这个makefile变数/参数就是用以实作这个功能。使用方法是在执行make时,将该变数指定为module的Android .mk。

  • make ONE_SHOT_MAKEFILE=

透过定义CREATE_MODULE_INFO_FILE , building system 会将所有module 资讯列在$(PRODUCT_OUT)/module-info.txt 档案里。

  • make CREATE_MODULE_INFO_FILE=true

设定BUILD_TINY_ANDROID=true , building system 产生一个简单的image , 以测试硬体的可用度。此功能用于移植的早期阶段,以快速bring up 。

HOST_BUILD_TYPE 和TARGET_BUILD_TYPE 指定building system 产生binary 的目的为debug 或release 。透过设定此二变数,能产生包含debug information 的binry 。

  • debug
  • release

这些参数,也可设于buildspec.mk 里,以避免开发过程不断的重新指定。

Goals

一般编辑整个Android系统,就是使用droid这个goal。droid会产生一个完整的系统,包括bootloader、kernel、系统程式、模组和应用程式。

showcommands 和droid 功能相同,但droid 在编译过程不显示所使用的指令。透过showcommands 这个goal, building system 显示过程中每一个步骤的详细指令。

Makefile 的流程

  • 初始化相关变数
  • 侦测编译环境和目标环境
  • 决定目标product
  • 读取product 的设定
  • 读取product 所指定之目标平台架构设定
    • 选择toolchain
    • 指定编译参数(*-.mk)
  • 清除输出目录
  • 设定/检查版本编号
  • 读取所有BoardConfig.mk 档案
  • 读取所有module 的设定
  • 根据设定,产生必需的rule
  • 产生image

以上的主要流程都是由build/core/main.mk 所安排。

初始化和侦测

由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
  • ......

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.. 形式的变数取得内容。

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.<path of="" Android.mk>.形式。例如, Android .mk定义了LOCAL_MODULE_SUFFIX ,变会存成ALL_MODULES.<path of="" Android.mk>.LOCAL_MODULE_SUFFIX 。Android .mk路径,当样会存于ALL_MODULES变数里。

Search Android .mk的路径,基本上会是整个source tree 。但会依特定的goal ,选择性只找寻特定目录。例如SDK只需特定目录下的Android .mk 。

Board Level 设定

和目标平台主板相关之设定,例如使用了什么装置、driver 等,或是是否需要编译bootloader 、 kernel 等,都是在BoardConfig.mk 里设定。同样,每张主板可以有不同设定,存在不同目录下的BoardConfig.mk ,以find 寻找如下档案:

  • build/target/board/$(TARGET_DEVICE)/BoardConfig.mk
  • vendor/*/$(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 以对映不同的主板。

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的building system其实不是那么复杂。在了解之后,也不是那么难修改。但, GNU make的一些语法,所building system使用一些不是那么直觉的用法,使的building system较难了解。但,花点心思就能克服。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值