
Android编译原理之make编译过程
iliuqi一、make
以高通的代码为例,高通在编译时使用如下的指令进行编译,实质是对make的封装
1 | ./build.sh --target_only |
在执行一系列check的函数后,最终调用make执行执行编译。而make函数是在build/envsetup.sh时声明。
从get_make_command函数可知,make后,真正然后执行编译的入口是:build/soong/soong_ui.bash
二、soong_ui.bash
- source microfactory.bash,得到一些函数命令, 例如:soong_build_go
- 编译/build/soong/cmd/soong_ui/main.go,生成 out/soong_ui这个可执行程序
- 执行命令:out/soong_ui –make-mode ,执行了make命令,会把”build/make/core/main.mk” 加到构建环境中,同时启动kati、blueprint-soong、ninja的编译。
1 | function gettop |
2.1 build/soong/scripts/microfactory.bash
build/soong/scripts/microfactory.bash
microfactory.bash得到build_go的函数命令,并提供 soong_build_go的函数执行方法并继续调用
build/blueprint/microfactory/microfactory.bash
GOROOT=prebuilts/go/linux-x86
2.2 build/blueprint/microfactory/microfactory.bash
build_go函数做了以下事情:
- 第一次执行编译时调用go run out/.microfactory_Linux/intermediates/src/microfactory.go编译出
microfactory_linux,第二次执行会执行检查,如果已编译则跳过go run
- 通过microfactory_Linux编译出soong_ui
soong_build_go soong_ui android/soong/cmd/soong_ui
build_go soong_ui android/soong/cmd/soong_ui
实际调用逻辑为:
1 | GOROOT=$(cd /prebuilts/go/linux-x86/; pwd) /out/microfactory_Linux |
从这儿可以知道soong_build_go soong_ui android/soong/cmd/soong_ui的意思就是从soong/cmd/soong_ui/下的go文件编译生成soong_ui
2.3 soong_ui的源文件main.go
soong_ui 是通过编译 build/soong/cmd/soong_ui/main.go得来
主要执行soong/ui/build/build.go,从build.go就可以看到执行soong的大体流程。
main.go中配置的toBuild为 BuildProductConfig | BuildSoong | BuildKati | BuildNinja,支持productconfig\soong\kati\ninja的构建
2.4 build.go流程
- runMakeProductConfig 主要配置编译参数
- runSoong 对工具进行编译,编译出blueprint等编译工具, 把*.bp 编译成 out/soong/build.ninja
- runKatiBuild, 加载 build/make/core/main.mk, 搜集所有的Android.mk文件生成ninja文件:out/build-${product}.ninja
- runKatiPackage, 加载build/make/packaging/main.mk, 编译生成out/build-aosp_arm-package.ninja
- createCombinedBuildNinjaFile,将out/soong/build.ninja 、out/build-aosp_arm.ninja和out/build-aosp_arm-package.ninja, 合成为out/combined-aosp_arm.ninja
- runNinja,运行Ninja命令, 解析combined-aosp_arm.ninja,执行编译过程
2.4.1 runMakeProductConfig
build/soong/ui/build/dumpvars.go
只是配置编译需要的参数
2.4.2 runSoong
主要功能:
- 对工具进行编译,编译出blueprint等编译工具
- 把*.bp 编译成 out/soong/build.ninja
2.4.2.1 Android R版本
runSoong()的执行过程:
- 执行build/blueprint/bootstrap.bash 生成.minibootstrap/build.ninja 和.bootstrap/build.ninja
- 生成minibp\bpglob
- 通过ninja来编译.minibootstrap/build.ninja 和.bootstrap/build.ninja
首先执行build/blueprint/bootstrap.bash
bootstrap.bash的作用:
- 它可以引导独立的blueprint来生成minibp二进制文件,可以直接运行 ./build/blueprint/bootstrap.bash。
- 也可以从另一个脚本调用它来引导基于Bleprint的自定义构建系统。
1 | func runSoong(ctx Context, config Config) { |
2.4.2.2 Android T版本
1 | func runSoong(ctx Context, config Config) { |
2.4.3 runKatiBuild
主要功能:
- 加载 build/make/core/main.mk
- 所有的Android.mk文件生成ninja文件:out/build-aosp_arm.ninja
1 | func runKatiBuild(ctx Context, config Config) { |
runKati中会启动Kati程序,开始解析main.mk
1 | $(info [1/1] initializing build system ...) |
最终是调用系统准备好的prebuilts/build-tools/linux-x86/bin/ckati参与编译,其中传入的参数有 –ninja\ –regen\–detect_android_echo 等,kati解析完build/make/core/main.mk后,就会⽣成相应的ninja编译规则,runKatiBuild()函数最后⽣成out/build-{product}.ninja⽂件
2.4.4 runKatiPackage
也是运行runKati,只不过携带的参数不同,runKatiPackage函数最后会生成out/build-{product}-package.ninja
2.4.5 createCombinedBuildNinjaFile
会将kati和soong_build两个程序⽣成的ninja⽂件都包含进来,再⽣成⼀个out/combined-${product}.ninja⽂件
2.4.6 runNinja
启动ninja程序解析out/combined-${product}.ninja⽂件,得到我们执⾏的命令⾥指定target-files-package模块的依赖⽂件,最后只要按照拓扑顺序挨个执⾏他们的rule去⽣成他们就可以了