Android编译系统
一.概述
在 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来进行构建工作。最终目标要把make都取代,于是从Android8.0开始,Google为了进一步淘汰Makefile,因此引入了Android.bp文件来替换之前的Android.mk。Android.bp只是一个纯粹的配置文件,不包括分支、循环语句等控制流程,本质上就是一个json配置文件。Android.bp 通过Blueprint+soong转换成ninja的构建规则文件build.ninja,再使用ninja来进行构建工作。这些文件之间的关系,如下图所示:

- kati是把Android.mk转换成ninja file。
- soong是把Android.bp转换成ninja file。
- Android.bp是jason形式组织的文件,将来逐步取代Android.mk
- 后续没有Android.mk,kati将会消失。
- ninja是同make编译构建系统一样,来替换make的,速度快。
- blueprint是一个处理Android.bp相关语法的库文件。
如下图为Android编译系统的演进:

谷歌官网的的Soong 构建系统介绍
二.编译流程
以Android10为例
2.1 编译构成
Android的编译目录在/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 编译步骤

三.编译环境初始化
3.1 envsetup说明
编译的第一步需要初始化一下环境变量。这是由envsetup.sh完成的,这里的envsetup.sh被link到了 build/make/envsetup.sh。
envsetup.sh 主要做了下面几个事情:

在source build/envsetup.sh后,输入hmm可以看到envsetup支持的一些接口:
| 命令 | 说明 |
|---|---|
| lunch | lunch <product_name>-<build_variant>选择<product_name>作为要构建的产品,<build_variant>作为要构建的变体,并将这些选择存储在环境中,以便后续调用“m”等读取。 |
| tapas | 交互方式:tapas [ ...] [arm/x86/mips/arm64/x86_64/mips64] [eng/userdebug/user] |
| croot | 将目录更改到树的顶部或其子目录。 |
| m | 编译整个源码,可以不用切换到根目录 |
| mm | 编译当前目录下的源码,不包含他们的依赖模块 |
| mmm | 编译指定目录下的所有模块,不包含他们的依赖模块 例如:mmm dir/:target1,target2. |
| mma | 编译当前目录下的源码,包含他们的依赖模块 |
| mmma | 编译指定目录下的所模块,包含他们的依赖模块 |
| provision | 具有所有必需分区的闪存设备。选项将传递给fastboot。 |
| cgrep | 对系统本地所有的C/C++ 文件执行grep命令 |
| ggrep | 对系统本地所有的Gradle文件执行grep命令 |
| jgrep | 对系统本地所有的Java文件执行grep命令 |
| resgrep | 对系统本地所有的res目录下的xml文件执行grep命令 |
| mangrep | 对系统本地所有的AndroidManifest.xml文件执行grep命令 |
| mgrep | 对系统本地所有的Makefiles文件执行grep命令 |
| sepgrep | 对系统本地所有的sepolicy文件执行grep命令 |
| sgrep | 对系统本地所有的source文件执行grep命令 |
| godir | 根据godir后的参数文件名在整个目录下查找,并且切换目录 |
| allmod | 列出所有模块 |
| gomod | 转到包含模块的目录 |
| pathmod | 获取包含模块的目录 |
| refreshmod | 刷新allmod/gomod的模块列表 |
3.2 Lunch说明
环境变量初始化完成后,我们需要选择一个编译目标。lunch 主要作用是根据用户输入或者选择的产品名来设置与具体产品相关的环境变量。

3.3 Make说明
执行完lunch命令后,就可以使用make命令来执行编译Build。
Android10.0上是通过soong执行编译构建,这里执行make命令时,main.mk文件把一些环境变量和目标都配置好后,会执行envsetup.sh中的make()进行编译。
如果找到“build/soong/soong_ui.bash”,就使用soong_ui.bash 来进行编译,否则使用原始的make命令进行编译。
四.总结
Android10.0中,mk文件通过kati\ckati编译生成 build-aosp_arm.ninja, bp文件通过blueprint-soong解析编译生成为build.ninja ,这些ninja文件会合并成combined-aosp_arm.ninja,最终通过ninja工具进行最终的编译。
参考:https://blog.csdn.net/yiranfeng/article/details/109082489?spm=1001.2014.3001.5501
Android编译系统的更多相关文章
- Android编译系统详解(一)
++++++++++++++++++++++++++++++++++++++++++ 本文系本站原创,欢迎转载! 转载请注明出处: http://blog.csdn.net/mr_raptor/art ...
- 深入浅出 - Android系统移植与平台开发(十)- Android编译系统与定制Android平台系统(瘋耔修改篇二)
第四章.Android编译系统与定制Android平台系统 4.1Android编译系统 Android的源码由几十万个文件构成,这些文件之间有的相互依赖,有的又相互独立,它们按功能或类型又被放到不同 ...
- 【转】Android编译系统详解(三)——编译流程详解
原文网址:http://www.cloudchou.com/android/post-276.html 本文原创作者:Cloud Chou. 欢迎转载,请注明出处和本文链接 1.概述 编译Androi ...
- Android编译系统入门(二)
Android.mk的使用方法 在上一篇Android编译系统入门(一)中我们只要介绍了Android系统使用make命令默认编译的依赖树是droid,而droid是一个伪目标,它有两个先决条件dro ...
- Android编译系统中的Android.bp【转】
本文转载自: 转自:http://note.qidong.name/2017/08/android-blueprint/ Android编译系统中的Android.bp.Blueprint与Soong ...
- Android编译系统(Android.mk文件详解)
[Android-NDK(Native Development Kit) docs文档] NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成a ...
- Android 编译系统的组成
Android 和 Linux 的编译系统都是通过 Makefile 工具来组织编译源代码的. Makefile 工具用来解释和执行 Makefile 文件,在 Makefile 文件里定义好工程源代 ...
- Android编译系统入门(一)
做过Android平台开发的朋友对make,mm或make clean命令应该很熟悉,但也许大家只是熟知这些命令的作用却不知道这些命令底下有些什么原理?那么今天我就带着大家推开Android编译系统的 ...
- Android编译系统简要介绍【转】
本文转载自:http://blog.csdn.net/luoshengyang/article/details/18466779 在Android源码环境中,我们开发好一个模块后,再写一个Androi ...
- Android编译系统参考手册
build/core/clear_vars.mk Clear out values of all variables used by rule templates 清除LOCAL变量,每个模块的And ...
随机推荐
- ajax中的同步异步和跨域请求
ajax中的同步异步和跨域请求 同步异步 demo.html <script> $.ajax({ type: "get", async: false, data: &q ...
- hv_balloon: Balloon request will be partially fulfilled. Balloon floor reached
windows 的hyper-v 安装了 centos 或者龙蜥 操作系统,会一直提示这个信息: hv_balloon: Balloon request will be partially fulfi ...
- Web入门:JavaScript文字动画
欢迎来的我的小院,恭喜你今天又要涨知识了! 案例内容 利用JavaScript实现文字逐步展现的动画效果. 演示 学习 <!DOCTYPE html> <html lang=&quo ...
- 【可观测性系列】 OpenTelemetry Collector的部署模式分析
作者简介:大家好,我是蓝胖子 ️博客首页:主页蓝胖子的编程梦 ️热门专题:我的服务监控实践 ,500行代码手写Docker **每日一句:白日莫闲过,青春不再来 大家好,我是蓝胖子,在前面我介绍了下O ...
- ABC306 A - F
ABC306 A - F 代码不提供 A 题意:吧字符串的每个字符连续输出两遍,记得不要快读,不要忘记输入 $ n $ 纪念 Qinzh A 题 WA 掉 B 题意:给定长度为 $ 64 $ 的数组 ...
- Java-将Oracle中某个表的数据导出成数据文件
在做数据开发或者ETL工作中,经常会遇到需要在客户端将Oracle数据库中的某些表的数据导出,提供给其他人员使用的情况. 下面介绍我之前实施的一种方法:(该方法不是最好的办法,但是可以勉强使 ...
- Java 21 虚拟线程如何限流控制吞吐量
虚拟线程(Virtual Threads)是 Java 21 所有新特性中最为吸引人的内容,它可以大大来简化和增强Java应用的并发性.但是,随着这些变化而来的是如何最好地管理此吞吐量的问题.本文,就 ...
- Optional 详解
1 前言 Optional 是 Java 8 的新特性,专治空指针异常(NullPointerException, 简称 NPE)问题,它是一个容器类,里面只存储一个元素(这点不同于 Conllect ...
- Swoole从入门到入土(9)——TCP服务器[协程风格]
上一篇,我们一起初步接触了协程.我相信只有一节的讨论,很多小伙伴对于"协程"与"线程"的区分可能还有点模糊.我们这里以两者的比较作为本篇开头,进行一番比较. 首 ...
- spring boot实现验证码登录
内容比较简单,需要完整项目的朋友留下邮箱,给你们发. 直接看效果: 下面是实现步骤 1.验证码生成工具类(引用自网络) package com.laoxu.test.helloweb.util; im ...