Android系统源码编译的一点实践

Android编译系统

目前公司的Android系统平台已经升级到Android 12了,最近迭代的系统项目涉及到Android 9、Android 10等,系统是庞大和复杂的,而源码调试工作需要一定的编译时间。在服务器争分夺秒的资源抢占下,即使寥寥几行代码的修改也能占据大部分编译时间,至此,如何提高系统源码的编译速度尤为重要。

Google对于编译工具和编译方式也在与时俱进,从最初的Android 7.0之前的Make,逐渐引入了Kati、Ninja、Blueprint、Soong编译或构建工具,同时编译配置文件Android.mk也逐渐被Android.bp取代。构建工具各司其责,协同工作,让Android源码能够精准而高效的生成所需产物。

  • 相关工具。
    Ninja:c/c++编写,只保留非常基本的对build操作的描述,目标是更快的编译。
    Kati:用于处理Android.mk文件,生成*.ninja文件。kati本身不进行编译,仅生成.ninja文件提供给Ninja进行编译。
    Blueprint:是生成、解析Android.bp的工具,是Soong的一部分。
    Soong:go语言实现的构建系统,整合.ninja文件,核心编译为soong_ui.bash。

  • 基本关系如下:

Kati
androidmk
Blueprint/Soong
Android.mk
Ninja
Android.bp

可以看出Android.mk和Android.bp最终都会生成ninja文件,最终是由Soong系统整合出最终的目标。 mk或bp文件的每次变动都会触发.ninja的生成。而大部分时候我们都是在增删改源文件,上百兆的.ninja文件不会每次都生成,基于此,我们可以直接编译已存在的.ninja,这样就减少了.ninja的编译生成时间。

编译的几点实践

  1. Android.bp替代Android.mk

Android S版本下system级别的app源码都采用了Android.bp作为编译配置,Soong作为核心编译系统发挥的作用也越来越大,如果vendor或package目录是自行开发的模块,建议编写Android.bp。
其中对于已有的Android.mk,可使用out/soong/host/linux-x86/bin目录下的androidmk工具,将Android.mk转换成Android.bp。

  1. 使用ninja大幅改进速度

AOSP在源码中已经内置了一个ninja执行文件:prebuilts/build-tools/linux-x86/bin/ninja
使用ninja,可以不经过make,直接执行ninja文件,完全避免重新生成,以及解析Makefile的运行开销。
使用ninja必须指定一个target,否则是全编译。 可以直接指定模块名,单独执行某个模块。 甚至可以指定具体的*.o、.jar、.dex文件为target,避免编译整个模块。

  • 比如编译jar
    在这里插入图片描述

对于编译某模块出现了错误:

FAILED: out/target/common/obj/APPS/OtaUpdate_intermediates/classes-full-debug.jar

编译其中间产物即可快速验证:

./prebuilts/build-tools/linux-x86/bin/ninja out/target/common/obj/APPS/OtaUpdate_intermediates/classes-full-debug.jar
  • ninja支持并发多任务编译的,适合依赖模块比较多的场景。
-f FILE  specify input build file [default=build.ninja]
-j N     run N jobs in parallel [default=22, derived from CPUs available]

指定-j参数,默认22

./prebuilts/build-tools/linux-x86/bin/ninja -f out/build-full_yxp_758_pad.ninja -j 22 OtaUpdate
  • 简化ninja编译命令,加入时间统计。
    增加设置环境变量的脚本方法:build/envsetup.sh
MY_NINJA_DEF="out/combined-full_${MY_DEVICE_NAME}.ninja"
function do_ninja() {
    
    
   time ./prebuilts/build-tools/linux-x86/bin/ninja -f ${MY_NINJA_DEF} $@
}
  • ninja使用的前提

要使用ninja需要先用make/mm/mmm等编译过一次才行,如果更改了文件目录结构、增删文件、git pull等操作,或者修改Makefile或Android.bp文件,还需要再重新make一次。记住这个前提,高效运用ninja编译能快速得到精准的结果。


  1. 使用ccache编译工具

ccache 加快重新编译速度的编译器缓存。如果经常使用make clean,或者经常在不同的编译产品之间切换,则非常适合使用ccache。

Android Q之前的系统自带了prebuilts/misc/linux-x86/ccache/ccache工具,后续高版本可从Android P版本拷贝过来也能使用。

在.bashrc文件中加入配置

export USE_CCACHE=1
export CCACHE_DIR=/MyCcachePath/.ccache

执行prebuilts/misc/linux-x86/ccache/ccache -M 50G可能会报 Could not set cache size limit 错误,修改缓存目录CCACHE_DIR的权限即可。

具体可参考:https://source.android.google.cn/source/initializing#optimizing-a-build-environment

猜你喜欢

转载自blog.csdn.net/qq_23069607/article/details/127113883
今日推荐