AOSP Microfactory
Microfactory
基于Android14.0.0_r73
简单介绍:
Microfactory是aosp的一个go语言编写的构建工具,且主要用于对go编译进行缓存,实现增量编译的效果。
源码
microfactory工具通过source build/blueprint/microfactory/microfactory.bash配置。
配置好以后shell中可以通过调用build_go函数触发并使用microfactory进行增量编译。
1 | build/blueprint/microfactory/microfactory.bash |
通过上述的分析可以发现microfactory的源码存储在$topdir/build/blueprint/microfactory不过实际在编译的时候会使用sed做一些简单的替换。
所以实际的microfactory的源码可以通过查找$topdir/out/.microfactory_$(uname)_intermediates/src 路径下查找
关于参数
microfactory作为一个构建工具,自然是可以传参的,那么参数有那些呢?可见下方
1 | // 编译时是否开启竞态检测器,对于于编译器的-race参数 |
源码分析
- 模板路径:
$topdir/build/blueprint/microfactory/microfactory.go
- 源码路径:
$topdir/out/.microfactory_Linux_intermediates/src/microfactory.go
main
没什么好讲的
1 | // 这段代码通过shell追加的 |
1.解释二进制参数
2.准备脚本运行时环境
3.将microfactory方法构建为二进制文件(构建自身的过程中会构建传入的源文件)
4.构建传入的参数信息
1 | func Main() { |
rebuildMicrofactory
首先需要说明一下microfactory是用来做源码的增量编译的,他是用于构建源码的工具
但是他在构建我们传入的源码前会先构建自身。而构建自身的逻辑就在如下rebuildMicrofactory中。
这个方法最核心的逻辑就是Build(config, mybin, “github.com/google/blueprint/microfactory/main”),接下来对Build方法进行分析
1 | // rebuildMicrofactory checks to see if microfactory itself needs to be rebuilt, |
Build
1 | func Build(config *Config, out, pkg string) (*GoPackage, error) { |
config.Path
这个方法是用来做package路径查找的,这里会输入一个go的包名,但是会返回一个包名所处路径。
值得注意的是这里的映射关系(即c.paths)是通过解析shell参数获得的。
1 | // Path takes a package name, applies the path mappings and returns the resulting path. |
FindDeps
最外层的FindDeps只是一层包装
1 | func (p *GoPackage) FindDeps(config *Config, path string) error { |
通过go标准库的ast解析能力对需要构建的文件的import/comment进行扫描。并将所有的依赖包记录到linkedDepSet中,方便后续编译 & 连接。
1 |
|
Compile
分为3个步骤:
1.编译前准备
a. 编译的command line准备
b. 当前构建的hash值计算
c. 通过拓扑排序优先让依赖的模块先触发构建
2.缓存逻辑
a.如果之前已经编译过尝试复用
b.将#1中计算的hash值与上次编译的hash进行对比如果一样则复用构建产物,不一样会重新触发一次构建
3.构建
a.如果#2处的构建失效了,那么就直接调用go编译器触发一次构建,中途会保存hash值方便缓存复用。
1 |
|
Link
逻辑如下
1.缓存
同上compile流程,计算hash值是否一样,一样就复用,不一样就重新link
2.链接
a.删除上一次的构建产物
b.拼接链接command line
c.执行link并将hash值写入到文件中
1 | func (p *GoPackage) Link(config *Config, out string) error { |