一,基础介绍
在 Android 7.0 之前,Android 编译系统使用 GNU Make 描述和shell来构建编译规则,模块定义都使用Android.mk进行定义,Android.mk的本质就是Makefile,但是随着Android的工程越来越大,模块越来越多,Makefile组织的项目编译时间越来越长。
从Android7.0开始,Google采用ninja来代取代之前使用的make,由于之前的Android.mk数据实在巨大,因此Google加入了一个kati工具,用于将Android.mk转换成ninja的构建规则文件buildxxx.ninja,再使用ninja来进行构建工作。Android8.0开始,Google为了进一步淘汰Makefile,因此引入了Android.bp文件来替换之前的Android.mk。
Android.bp只是一个纯粹的配置文件,不包括分支、循环语句等控制流程,本质上就是一个json配置文件。Android.bp 通过Blueprint+soong转换成ninja的构建规则文件build.ninja,再使用ninja来进行构建工作。
Google在 Android 7.0之后,引入了Soong构建系统,旨在取代make,它利用 Kati GNU Make 克隆工具和 Ninja 构建系统组件来加速 Android 的构建。
Android系统的编译历程:
2 编译流程
2.1 编译构成
Android的编译目录在/build 中,看一下Android 10源码中的build目录,现在是这个样子:
这个目录中可以看到core文件夹被link到了make/core,envsetup.sh被link到make/envsetup.sh,这主要是为了对使用者屏蔽切换编译系统的差异。
这里重点看四个文件夹:blueprint、kati、make、soong
blueprint:用于处理Android.bp,编译生成*.ninja文件,用于做ninja的处理
kati:用于处理Android.mk,编译生成*.ninja文件,用于做ninja的处理
make:文件夹还是原始的make那一套流程,比如envsetup.sh
soong:构建系统,核心编译为soong_ui.bash
Soong编译系统家族成员及各自关系如下图所示:
在编译过程中,Android.bp会被收集到out/soong/build.ninja.d,blueprint以此为基础,生成out/soong/build.ninja
Android.mk会由kati/ckati生成为out/build-aosp_arm.ninja
两个ninja文件会被整合进入out/combined-aosp_arm.ninja
2.2 编译步骤
source build/envsetup.sh
lunch aosp_arm-eng // 或者 m PRODUCT-aosp_x86_64-eng ,Android10.0不一定需要lunch命令
make -j8 //编译模块也可以直接用 m libart
编译步骤如下图所示:
3 编译环境初始化
3.1 envsetup说明
编译的第一步需要初始化一下环境变量,通过以下命令完成:
source build/envsetup.sh
这里的envsetup.sh被link到了 build/make/envsetup.sh
envsetup.sh 主要做了下面几个事情:
3.2 Lunch 说明
环境变量初始化完成后,我们需要选择一个编译目标。lunch 主要作用是根据用户输入或者选择的产品名来设置与具体产品相关的环境变量。
如果你不知道想要编译的目标是什么,直接执行一个lunch命令,会列出所有的目标,直接回车,会默认使用aosp_arm-eng这个目标。
3.3 soong的编译过程
执行runKatiBuild时,有个重要的步骤,就是加载build/make/core/main.mk,main.mk文件是Android Build系统的主控文件。从main.mk开始,将通过include命令将其所有需要的.mk文件包含进来,最终在内存中形成一个包括所有编译脚本的集合,这个相当于一个巨大Makefile文件。Makefile文件看上去很庞大,其实主要由三种内容构成: 变量定义、函数定义和目标依赖规则,此外mk文件之间的包含也很重要。
3.4.工具链的关系
Android.mk文件、Android.bp、kati、Soong、Blueprint、Ninja之间的关系如下:
Android.bp --> Blueprint --> Soong --> Ninja
Makefile or Android.mk --> kati --> Ninja
(Android.mk --> Soong --> Blueprint --> Android.bp)
Blueprint是生成、解析Android.bp的工具,是Soong的一部分。Soong则是专为Android编译而设计的工具,Blueprint只是解析文件的形式,而Soong则解释内容的含义。
Android.mk可以通过Soong提供的androidmk转换成Android.bp,但仅限简单配置。目前Oreo的编译流程中,仍然是使用kati来做的转换。
现存的Android.mk文件、既有的Android.bp,都会分别被转换成Ninja。从Android.mk与其它Makefile,会生成out/build-<product_name>.ninja文件。而从Android.bp,则会生成out/soong/build.ninja。此外,还会生成一个较小的out/combined-<product_name>.ninja文件,负责把二者组合起来,作为执行入口。
最终,Ninja文件才是真正直接控制源码编译的工具。
————————————————