Android系统的模块编译调试方法、android系统给apk生成系统模块jar包的方法、ninja的使用

一、模块编译调试方法:

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

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

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

           完成根目录下完成source build/envsetup.sh命令、lunch qssi-userdebug-mars命令(准备好编译环境、选择好编译分支,才可以开始编译)

           整编命令如 bash build.sh -j32 dist --qssi_only 2>&1 | tee buildlog.log

           模块编译如下:

 

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/下面重启即可。(-j参数是开线程数量,多少内核就开多少数量,这样编译快一点)

 

2. 修改位于framework/base/services下的东西,在执行source build/envsetup.sh命令的版本源代码根目录执行make services -j32

产物位于out/target/product/qssi/system/framework下面,拿出来push到手机的/system/framework/下面重启即可。

 

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再重启)

在framework/base下的其他很多目录下的代码修改也可以被编译到,但需要自行确认:1、故意改错去编译2、搜Android.bp文件内容看看framework-minus-apex library的srcs是否包含了被修改的文件。

作SDK:如果是要make出jar包给apk调用而不是push到系统里调试,那要拿此目录的jar包:out/target/common/obj/JAVA_LIBRARIES/framework-minus-apex_intermediates/classes.jar。其他模块的编译也是一样的找法。

(版本改动注意:)

 

4. 修改位于frameworks/native/cmds/abcd的任意模块代码,通过make abcd -j32编译

比如make installd -j16   make atrace -j16等

产物位于out/target/product/qssi/system/bin下面,拿出来push到手机的system/bin/下面重启即可。

 

5. 修改位于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可以编译到被修改文件

(  Android Pony EXpress (APEX) 是 Android 10 中引入的一种容器格式,用于较低级别系统模块的安装流程中。此格式可帮助更新不适用于标准 Android 应用模型的系统组件。一些示例组件包括原生服务和原生库、硬件抽象层 (HAL))、运行时 (ART) 以及类库。)

 

5. 改动SystemUI、Settings等模块的代码,可以通过make SystemUI 、make Settings来进行编译产物在/system/app  or  /system/priv-app下面,将结果apk直接install,然后重启此应用相关服务,如直接重启手机,或者如SystemUI在install后adb shell am restart也可以。

不要push 已经存在的apk到手机,重启系统不会扫描,新的apk不会重新安装,测试效果将还是原先的效果,除非此系统apk可以先删掉重启再push再重启。

 

6. 通用编译模块的方法如修改位于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重启。

7.当你确定修改的内容能在编译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就可以省去第一部分耗时,尤其在反复编译时调试效率提高。

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

ninja的获取:

先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文件内容:

#!/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进行快速编译时,遇到如下错误:

ninja: error while loading shared libraries: libjemalloc5.so: cannot open shared object file: No such file or directory

使用如下解决方法:

sudo cp prebuilts/build-tools/linux-x86/lib64/libjemalloc5.so /usr/lib

 

 

转载请注明原地址连接,感谢你的阅读

posted @ 2022-12-06 18:48  小汀  阅读(2165)  评论(0编辑  收藏  举报