Android系统模块编译调试与Ninja使用指南

模块编译调试方法

(此处举例framework、installd、SystemUI等模块的编译调试,其他类似)

1. Framework模块编译

Android系统代码的framework目录内,一共有3个模块单独编译:framework、services、framework-res.apk。

注意:偶尔会有改了代码但没检测到,编译结束后产物并未更新的情况,所以可以考虑先剪切掉原先的产物或者检查产物更新时间确保已经重新编译。

步骤:

  1. 完成根目录下 source build/envsetup.sh 命令、lunch qssi-userdebug-mars 命令(准备好编译环境、选择好编译分支,才可以开始编译)。
  2. 整编命令如 bash build.sh -j32 dist --qssi_only 2>&1 | tee buildlog.log。
1.1 修改frameworks/base/core/res下的内容
  • 在执行 source build/envsetup.sh 命令的版本源代码根目录执行 make framework-res -j32。
  • 产物位于 out/target/product/qssi/system/framework 下面(如 framework-res.apk 之类),push到手机的 /system/framework/ 下面重启即可。
1.2 修改framework/base/services下的内容
  • 在执行 source build/envsetup.sh 命令的版本源代码根目录执行 make services -j32。
  • 产物位于 out/target/product/qssi/system/framework 下面,拿出来push到手机的 /system/framework/ 下面重启即可。
1.3 修改framework/base/core下的内容
  • 在执行 source build/envsetup.sh 命令的版本源代码根目录执行 make framework-minus-apex -j32。
  • 产物位于 out/target/product/qssi/system/framework 下面,拿出来push到手机的 /system/framework/ 下面重启即可。
  • 问题处理 :如果卡在开机过程里(常在小于Android13版本中发生),而且不是自己原因导致而是一些AndroidRuntime错误导致的signal 6的内存错误,可尝试在push framework.jar 后 adb shell rm -rf system/framework/oat system/framework/arm system/framework/arm64 再重启。
1.4 其他目录下的代码修改
  • 在framework/base下的其他很多目录下的代码修改也可以被编译到,但需要自行确认:
    • 故意改错去编译。
    • 搜Android.bp文件内容看看framework-minus-apex library的srcs是否包含了被修改的文件。
1.5 作SDK
  • 如果是要make出jar包给apk调用而不是push到系统里调试,那要拿此目录的jar包:out/target/common/obj/JAVA_LIBRARIES/framework-minus-apex_intermediates/classes.jar。
  • 版本改动注意 :在Android11之前修改了framework相关代码,只需 make framework 就可以编译出 framework.jar。在Android11,这个编译命令不起作用了,根据framework/base/目录下Android.bp中的提示,编译命令需要改为 make framework-minus-apex。

2. 修改frameworks/native/cmds/abcd的任意模块代码

  • 通过 make abcd -j32 编译,比如 make installd -j16 make atrace -j16 等。
  • 产物位于 out/target/product/qssi/system/bin 下面,拿出来push到手机的 /system/bin/ 下面重启即可。

3. 修改packages/modules/abcd的代码

  • 通过找被修改文件属于的同/上级目录的Android.bp文件中哪个模块内编译,在此模块library中找到apex_available标签,即标识该library可以被name为xxxx的apex包进去,通过 make xxxx -j32 编译。
  • 产物位于 out/target/product/qssi/system/apex/ 下面,拿出来push到手机的 /system/apex/ 下面重启即可。
  • 示例 :修改了 /packages/modules/Wifi/framework/java/android/net/wifi/WifiManager.java,那么在 /packages/modules/Wifi/framework/Android.bp 中找到 apex_available: ["com.android.wifi", "test_com.android.wifi"],就知道 make com.android.wifi -j16 可以编译到被修改文件。

4. 改动SystemUI、Settings等模块的代码

  • 可以通过 make SystemUI、make Settings 来进行编译,产物在 /system/app 或 /system/priv-app 下面,将结果apk直接install,然后重启此应用相关服务,如直接重启手机,或者如SystemUI在install后 adb shell am restart 也可以。
  • 注意:不要push已经存在的apk到手机,重启系统不会扫描,新的apk不会重新安装,测试效果将还是原先的效果,除非此系统apk可以先删掉重启再push再重启。

5. 通用编译模块的方法

  • 如修改位于 framework/native/services 下的文件,可以通过在同级或上级目录中的Android.bp文件内容中查找修改的文件名字或具体目录,来找到所属sources,再逐级向上找到被编译进哪个"name"的目标产物xxx中,再 make xxx -j32 对其编译。
  • 如果xxx编译出的产物是中间产物或手机中没有的无法替换的产物可以再向上查找更大name的目标产物xxxx(如:cc_library_shared、cc_library、java_library、apex_available等)进行编译或直接push进system/lib和system/lib64重启。

6. 编译system.img

  • 当你确定修改的内容能在编译system.img时带入,可以使用 make systemimage -j16 编译。通过进入fastboot模式后刷system.img进行生效。

编译调试注意点

  1. 编译最好把已经生成的先删掉,不然有可能文件不更新(push前check下文件的生成时间)。
  2. 编译终端最后提示的生成路径不一定是唯一生成路径,同级目录、对称lib或lib64目录里可能都有你需要的生成物。library要把生成的库文件在system/lib和system/lib64下都做相应的push。
  3. 如果是push替换库文件,最好留一个原本的备份避免push了开不了机器。
  4. 编译调试的时候如果是自己陌生的模块,建议每次都加行特殊log以确认自己的修改已经生效。

二、使用ninja替代make进行快速编译

为什么要使用ninja?

通常使用make编译会有两个阶段:

  1. 先分析Android.bp,将所有需要参与编译的文件的路径都记录下,writing build rules并打包到 out/soong/combined-.ninja 中。(普遍耗时15-20min)
  2. 然后ninja工具通过第一步生成的文件,编译要编译的模块。(不同模块速度不同,比如services模块只需要大约20s)

优点:直接使用ninja就可以省去第一部分耗时,尤其在反复编译时调试效率提高。

注意点

  1. 进行ninja之前必须要先make一次(当然要想make必须先根目录source和lunch一次),以生成路径文件;如果你的修改增删了模块中文件的名字路径,就必须重新make生成路径文件。

ninja的获取

bash 复制代码
cd到android系统源码的根目录下,执行
cp prebuilts/build-tools/linux-x86/bin/ninja out/host/linux-x86/bin/
cp prebuilts/build-tools/linux-x86/bin/ninja /usr/local/bin/
cp prebuilts/build-tools/linux-x86/bin/ninja /usr/bin/
ln -sf out/combined-***.ninja build.ninja

ninja文件内容

bash 复制代码
#!/bin/bash
ninja(){
 ninja_bin="$ANDROID_BUILD_TOP/prebuilts/build-tools/linux-x86/bin/ninja"
 ninja_build_file="$ANDROID_BUILD_TOP/out/combined-$TARGET_PRODUCT.ninja"
 if [ ! -f $ninja_build_file ]
 then
 echo "can't find ninja buildfile $ninja_build_file"
 exit -1
 fi
 if [ ! -f $ninja_bin ]
 then
 echo "can't find ninja binary $ninja_bin"
 exit -1
 fi
 $ninja_bin -f $ninja_build_file $1
 }
#usage:ninja<modulename>
ninja $*

ninja的执行

如果执行ninja进行快速编译时,遇到如下错误:

bash 复制代码
ninja: error while loading shared libraries: libjemalloc5.so: cannot open shared object file: No such file or directory

使用如下解决方法:

bash 复制代码
sudo cp prebuilts/build-tools/linux-x86/lib64/libjemalloc5.so /usr/lib
相关推荐
千里马学框架2 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui