【写在前面】
网上资料梳理,侵删烦请联系。或有表达错误,欢迎指出纠正。
【参考引用】
https://www.it610.com/article/1292218615122173952.htm
https://blog.csdn.net/xiehaihit/article/details/92642127
http://blog.csdn.net/mr_raptor/article/details/7539978
系统编译
编译系统
Makefile脚本
- 是什么
一个脚本文件,与普通的shell脚本文件相似,只不过遵循Makefile语法。 - 有何用
描述文件之间的依赖关系,以及怎么处理这些依赖关系。
用于构建make编译的规则文件。
Android.mk文件
- 是什么
一个Makefile脚本,用来描述模块编译信息。
Android编译系统通过整合Android.mk文件完成编译过程。
Make编译
- 有何用
通过执行makefile文件,处理文件之间的依赖关系。
Android编译环境初始化后,可以用m/mm/mmm/make命令编译源代码。
当一个*.c文件include的*.h文件发生变化时,需要重新编译该*.c文件。
- make/mm编译慢的原因
①全编时,需要find所有Android.mk和Android.bp,耗时比较长,导致make时电脑卡住,不能进行其它操作。
②每次source/lunch完成,厂商预装逻辑会动态生成一个app_config.mk,虽然内容不会变化但是会修改时间戳,导致make的时候需要重新生成ninja文件;
③执行真正编译前,build系统需要检查ninja文件是否需要更新?soong环境是否正常?如果不是,需要进行soong_ui相关初始化,例如查找全部的Android.mk/Android.bp检查lastModifiedTime,检查microfactory/minibp/soong_ui/soong_build等是否完成,以及动态配置各种config。
ninja编译
- 是什么
编译框架,根据相应的ninja格式的配置文件进行编译。
一般不会手动修改,通过将Android.bp文件转换为ninja格式文件来编译。 - 有何用
取代make。
ninja 在大的项目管理中速度和并行方面有突出的优势。 - 快速编译
ninja编译时,无法重新解析mk文件,会使用上次生成的 ninja build 文件,比较省时;
使用ninja需要先用make/mm/mmm等编译过一次才行,如果更改了文件目录结构、增删文件、repo sync等操作,或修改Makefile或Android.bp文件,还需要重新make一次。
kati编译
- 有何用
将Android.mk转换为build.ninja。
在Android全编后,可以使用ninja编译已经生成的.ninja文件。
Android.bp文件
- 是什么
本质上是一个json 配置文件。不包括分支、循环等流程控制。 - 有何用
替代Android.mk。
Soong工具
- 是什么
类似于Makefile编译系统的核心,负责提供Android.bp语义解析,并将之转换成Ninja文件。 - 有何用
将 Android.bp 转换为build.ninja。
注:无论是 Android.mk 还是 Android.bp,最后都转化成 ninja 的构建规则,再进行编译。
Blueprint工具
- 是什么
生成、解析Android.bp的工具,是Soong的一部分。
总结:
Soong—负责Android编译而设计的工具;
Blueprint—解析文件格式;
Soong—解析内容的具体含义。
Soong和Blueprint是Google谷歌为Android.bp特别定制的工具,不单独操作。
Soong、Blueprint、Kati、Ninja之间的关系
Android编译过程
out目录下生成.ninja文件,遵循ninja语法,通过ninja命令来编译;
①进入makefile执行;
②若没有build.ninja,则生成;
③生成目标ninja
④编译生成odex
build/envsetup.sh
- source build/envsetup.sh
- 有何用
在vendor和device两个目录将厂商指定的envsetup.sh也source到当前shell当中,从而获得厂商提供的产品配置信息。
- 有何用
- lunch
对编译环境进行初始化,主要指定编译的类型和目标设备的型号。
执行过程如下:
(1)设置环境变量,指定目标产品类型和编译类型。
(2)通过make命令执行Makefile脚本,配置目标产品型号的相关信息。
编译类型
Android的编译类型主要有eng、userdebug和user三种,而支持的目标设备型号则是不确定的,由当前的源码配置情况所决定。
eng:工程机
user:最终用户机
userdebug:调试测试机
tests:测试机
为了确定源码支持的所有目标设备型号,Android编译系统在初始化的过程中,需要在特定的目录中加载特定的配置文件。
编译步骤
(1)source build/envsetup.sh
//加载命令
(2)lunch
//选择平台编译选项
(3)make
//执行编译。即执行当前目录下的Makefile文件。
m/mm/mmm
- m
相当于执行make命令。对整个Android源码进行编译。 - mm
在Android源码根目录下执行,相当于执行make命令对整个源码进行编译。
在Android源码根目录下的某一个子目录执行,则从该子目录开始,一直往上一个目录直至到根目录,寻找是否存在一个Android.mk文件。如果存在,就通过make命令对该Android.mk文件描述的模块进行编译。 - mmm
后面可以跟一个或者若干个目录。
如果指定了多个目录,那么目录之间以空格分隔,并且每一个目录下都必须存在一个Android,mk文件。
如果没有在目录后面通过冒号指定模块名称,那么在Android.mk文件中描述的所有模块都会被编译,否则只有指定的模块会被编译。
如果需要同时指定多个模块,那么这些模块名称必须以逗号分隔。