摘要:如何通过Ninja来提升Android编译速度
1.概述
上一节我们了解了Ninja的作用,虽然ninja相比make来说,提升了编译时间,但是当我们需要增量一个修改时,依旧需要花费不少时间,从log中,经常能看到前期花了很长时间,才走到“Starting ninja”这个字段,在这之前一直在做准备,那么我们要想办法提升一下ninja增量的编译速度。
2.编译分析
从Android O开始,soong已经是google的入口。从soong入口后,会经soong_ui,soong,kati,blueprint几个阶段,把mk,bp转换成ninja文件后,然后执行ninja命令解析ninja文件进行编译。
如下图所示整个编译过程,准备过程非常冗长。
每次编译都要重新收集所有的文件、.mk、.bp的修改,然后重新生成build.ninja,在合并成combined-aosp_arm.ninja。
大部分情况下,研发的工作是不断的修改.c .h .cpp .java 然后增量,此时真正的编译工作是非常少的,这样相对而言,准备工作往往是占大头的,所以我们可以考虑舍弃combined-aosp_arm.ninja之前的准备过程。
这里以增量编译init_system为例,之前我们已经编好了init_system,然后如果我们继续用m命令单编init_system,需要2分钟。
-
ingresge:
~
/AP
/AOSP_Q$
time m init_system
-
[
100
%
6336
/
6336] Install:
out
/target
/product
/generic
/fake_packages
/init_system
-
timestamp
-
-
#### build completed successfully (
02:
37 (mm:ss)) ####
-
-
real
2m36
.672s
-
user
43m51
.510s
-
sys
2m51
.991s
为了对比编译时间,我们直接抛弃了编译的环境和ninja文件生成的逐步过程,我们使用下面的命令直接跑ninja,结果只花了5秒。
命令:
time prebuilts/build-tools/linux-x86/bin/ninja -v -d keepdepfile init_system -f out/combined-aosp_arm.ninja -w dupbuild=err
编译结果:
-
ingresge:
~
/AP
/AOSP_Q$
time prebuilts
/build
-tools
/linux
-x86
/bin
/ninja
-v
-d keepdepfile init_system
-f
out
/combined
-aosp_arm.ninja
-w dupbuild
=err
-
[
7
/
7]
/bin
/bash
-c "(rm -f out/target/product/generic/system/bin/init ) && (cp out/target/product/generic/obj/EXECUTABLES/init_second_stage_intermediates/init out/target/product/generic/system/bin/init )"
-
-
real
0m5
.351s
-
user
0m14
.752s
-
sys
0m3
.201s
3.qninja提升编译速度
根据上一节分析到,舍弃combined-aosp_arm.ninja的准备过程,直接指向ninja可以提升速率,因此我们可以开发一个快速的编译命令,来提升研发的编译效率。
我们可以在修改build/make/envsetup.sh,新增一个qninja函数。
-
function
qninja()
-
{
-
local cmdline=
"time prebuilts/build-tools/linux-x86/bin/ninja -v -d keepdepfile $@ -f out/combined-aosp_arm.ninja -w dupbuild=warn"
-
echo
$cmdline
-
$cmdline
-
}
只是修改了某个模块中的.c .h .cpp .java后,进行增量,编译命令如下:
-
source build/envsetup.sh
-
qninja init_system
最终的编译时间仅仅花费了5秒:
-
real
0m5
.351s
-
user
0m14
.752s
-
sys
0m3
.201s
4.总结
其实本节是提高了增量编译的速率,但是如果我们新增了.c .c++或者修改了.mk\.bp 的文件化,需要重新指向kati、soong的过程,用于手机新增文件或者新增编译参数的变化,最终重新生成combined-aosp_arm.ninja来参与编译,这个编译的速率还是会慢一些。需要在开发过程中注意这一点,以免引起qninja编译模块不生效的问题。