做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
未完待续.......