做android 系统调试的时候,很多情况下,我们修改很少的文件,如果我们整编的话,就会很浪费时间,这种情况我们就会考虑单编,至于单编应该怎么替换生成的系统文件呢,下面这些是我调试的时候总结的经验,供大家参考.

首先说单编应该怎么选择module name 呢

每个模块都有对应的bp 或者mk(mk 和bp 网上很多教程,暂时不过多说明) ,如果没有就往上层路径查找,对应名字(用grep -rnws --include='*.bp' 'name:'也可以查找),如果不清楚,也可以用绝对路径进行编译,编译指令如下

命令

解释

例子

mm

对应模块名字编译,但是不编译依赖模块

mm Settings

mmm

编译指定目录下的模块,但是不编译依赖模块

mmm packages/apps/Settings

mma/make

编译指定目录下的模块,包含依赖模块

mmm packages/apps/Settings Settinglib

mmma

编译指定目录下的所有模块,包含依赖模块

mmm packages/apps

很多人编译的时候发现没有生效,可能是修改的是依赖库,选择的命令不对,正确选择编译即可. 

1,替换apk

这个最简单,也是做到的最多的,以SystemUI 为例

编译mm SystemUI  ,生成路径/out/target/product/项目名字/product/priv-app/SystemUI/SystemUI.apk

替换adb push /out/target/product/项目名字/product/priv-app/SystemUI/SystemUI.apk  /product/priv-app/SystemUI/SystemUI.apk  ,然后重启即可生效

2,编译framework

make framework-minus-apex -j8  (-j8 表示启动8核快速编译)

替换:adb root;adb remount;

adb push out/target/product/项目名字/system/framework/framework.jar system/framework/;

adb push out/target/product/项目名字system/framework/arm/* system/framework/arm/;

adb push out/target/product/项目名字/system/framework/arm64/* system/framework/arm64/;

adb reboot

3,编译selinux

selinux 分为system 和 vendor,一般我们只修改vendor 下面,但是系统会整合system和vendor,所以我们不用管,一起编译替换即可

make selinux_policy

替换:一般生成在下面的路径,只有要都替换,同样,重启生效

adb push out/target/product/项目名字/system/system_ext/etc/selinux/* system_ext/etc/selinux/;

adb push out/target/product/项目名字/vendor/etc/selinux/* /vendor/etc/selinux/;

adb push out/target/product/项目名字/system/etc/selinux/* /system/etc/selinux/;

adb push out/target/product/项目名字/system/product/etc/selinux/* /product/etc/selinux/

 4,编译services

mm services

adb root;adb remount;adb push out/target/product/项目名字/system/framework/services.jar /system/framework/;

adb push out/target/product/项目名字/system/framework/oat/arm64/services.* /system/framework/oat/arm64/;adb shell sync;adb reboot

5,编译feature

方式1:参考系统路径下的方式frameworks/native / data/etc/自定义.xml

<permissions>
    <feature name="com.google.android.feature.xxxx />
</permissions>

mk 文件中添加即可,重启系统会自动解析该路径文件:

PRODUCT_COPY_FILES += frameworks/native/data/etc/自定义.xml$(TARGET_COPY_OUT_VENDOR)/etc/permissions/自定义.xml

方式2:自定义文件可以随便放,通过mk 文件的方式编译,生成到指定路径

LOCAL_PATH := $(my-dir)


########################

include $(CLEAR_VARS)


LOCAL_MODULE := 自定义.xml

LOCAL_MODULE_TAGS := optional


LOCAL_MODULE_CLASS := ETC


# This will install the file in /system/etc/permissions

#

LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions


LOCAL_SRC_FILES := $(LOCAL_MODULE)


include $(BUILD_PREBUILT)

添加到系统编译文件中去

PRODUCT_PACKAGES += 自定义.xml

一般rc 文件,和脚本文件都是可以直接push 替换的,不需要编译

5,ninja 编译


之前同事总结的,关于android 10及以上 单编译模块速度慢的问题  主要是因为 在mm  build的过程中 去调用了


subdir_makefiles := $(SOONG_ANDROID_MK) $(file <$(OUT_DIR)/.module_paths/Android.mk.list) $(SOONG_OUT_DIR)/late-$(TARGET_PRODUCT).mk
 subdir_makefiles_total := $(words int $(subdir_makefiles) post finish)
 .KATI_READONLY := subdir_makefiles_total


等方法 需要搜索  所有的 BP 和 android.mk  和生成 新的ninja 文件 导致编译过慢



我们可以在build/make/envsetup.sh
新增一个singleninja函数



function singleninja()
 {
     local cmdline="time prebuilts/build-tools/linux-x86/bin/ninja -v -d keepdepfile $@ -f out/combined-项目名字.ninja -w dupbuild=warn"
     echo $cmdline
     $cmdline
 }

添加完. build/envsetup.sh 就可以生效

比如说singleninja Settings 就会发现很快就编译好了

6,编译init

make init 或者上面的singleninja init

替换 adb push out/target/product/productname/system/bin/init  system/bin/init ;adb reboot 即可

7,编译framework-res

修改framework/base/core/res/   下面的字符串或者config 等配置的时候,就可以单独编译这个替换

mm framework-res, make framework-res 或者上面的singleninja framework-res

adb push out/target/product/项目/system/framework/framework-res.apk   system/framework/framework-res.apk


未完待续.......