关于编译相关的总结
1. Make、Soong
source的时候会配置本地的环境变量,构建文件的软链接,以及生成lunch命令、get_var等等,具体的查看build/envsetup.sh。
然后lunch的时候根据选择的product来决定执行哪些编译选项,编译哪些mk,也就是在mk中的PRODUCT相关的变量都通过lunch来决定。
然后具体的编译代码最底层使用的还是gcc等编译成二进制可执行文件,当然因为整个源码庞大,需要先生成中间产物,也就是下面说的。
以前的mk文件由linux自带的makefile编译控制,mk文件就是make的配置;现在 mk文件由kati读取,并转为ninjia。
关于make和soong多讲来句,make并不是linux本身的一个功能,make也是一个工具,
Sudo apt-get install make
只不过现在ubuntu等linux内核的系统,发行时自带了这一安装包,所以不需要安装。
而现在的bp文件依赖的soong,其实就是编译时生成的soong_ui,在out目录下。
而生成soong_ui这个二进制程序依赖的就是soong_ui.bash这个bash脚本,其中又依赖go工具编译,最终生成二进制文件。
具体的Soong_ui.bash编译的逻辑,参考这篇文章,分析的不错:
https://gitee.com/aosp-riscv/working-group/blob/master/articles/20210111-soong-process.md
就不要重复造轮子了。以后有新的理解再补充。
然后现在mk正在转为bp文件,Android.bp,bp文件由soong读取,转为ninjia,bp文件和mk文件本质上是一样的,都是配置文件,mk文件配置Make,bp文件配置soong。最终编译系统执行编译时读取的是ninjia文件,ninjia文件就是整个编译过程所有的规则(rule),非常简单,但是多!因为每个文件就是一个规则,这是最简单的方式,当然还有一些pool的方式,一组文件执行一个规则,减少时间。
这样的好处是对于单个模块来讲,编译一次,不属于自己模块的可以直接拿上次的编译结果来编译,不用重新编译,加快开发。
但是对于底层适配来说,每次的改动都得重新编译,都得重新生成一次ninjia,完整的编译需要三四个小时,什么都干不了,即使只改动一点点代码,也还是要耗费几个小时重新编译。
简单来说,对于应用层来说,是好事。但是对底层来说,还是阵痛期。除非整个源码都使用一种编译方式,也就是全部转为bp文件,应该编译会快很多。
但是bp文件不支持条件语句,也不包含控制流语句;为了解决这些问题,又只能引入go语言来进行解决,又搞得复杂了。bp可以生成哪些module,由soong_build.html控制。
大神的仓库:
https://gitee.com/aosp-riscv/working-group
最后总结一句题外话,如上面文章作者说的,既然谷歌都已经宣布bazel了,说明Soong已经没必要纠结了,在上面浪费大量时间,是不可取的。不如直接了解bazel,至于为什么这么说下面简单介绍。
2. Bazel
bazel的配置文件叫做BUILD.bazel。
为什么说应该主要了解bazel,因为bazel官网都有了,soong只有个readme。。
bazel官网:https://bazel.build/
另一个原因是谷歌自家的应用都使用这个bazel编译系统了,自家所有的应用,可想谷歌的推行力度之大。安卓官网也写了:
Google 计划使用几年的时间将 Android 构建系统迁移到 Bazel。此迁移处于早期阶段,但您可以对当前的 build 文件做出一些更改,以便开始针对 Bazel 做好准备。迁移完成后,Bazel 将取代 AOSP 中的所有现有构建系统和 build 配置系统(Make、Kati、Soong、基于 Make 的产品配置)。
看最后一句,谷歌想把编译相关的任务都交给bazel来做。大工程,安卓代码太庞大了,不知道什么时候能够完成。。
bazel官网关于编译系统的介绍 https://bazel.build/basics
3. bazel何时完全支持Android还未知
所以还是继续了解soong,下一步有时间把soong的readme翻译一下。