====
[欢迎转载,保留链接] 安卓编译进阶<Android:boot art+oat>功能的打包与取消及追溯代码思路历程
####
http://blog.csdn.net/rancec/article/details/77450450
点击打开:安卓编译进阶功能的打包与取消及追溯代码思路历程
****
====
导读:
####
之前接手了新平台,是5.x版本的系统,可以说算是很旧的了,2015年出品就用过,不过跳转产品后系统变得很旧,多数时间还是kitkat的,这个有行业的准则影响;
发现本题目,是因为在更改FW的时候,居然没有正常的android.policy.jar生成,故此追溯代码,做个基本的小研究,更深入的了解编译的局部原理;
****
====
####
一、 ****
首先,用如下命令导入shell环境变量的配置(. ./build/envsetup.sh 亦可)并编译安卓全局项:
source ./build/envsetup.sh && lunch aosp_xxx-userdebug && make propclean / installclean && make -j8
编译说明:
make -j8 -- 抛出八个线程并行编译,可以有效利用CPU/DDR性能,如果不知道合适的参数,可以用-j,系统会根据硬件配置自动匹配最佳的,但太多了会较卡,普通电脑推荐-j4,服务器-j8;
make propclean -- propclean是用来删除build.prop的快捷方法,不必寻找target做匹配;
make installclean -- propclean是用来删除system的,某些需要删除才能强制更新的文件,需求执行此步骤,如/system/etc下面的配置文件等;
一般来说编译完整个安卓后,才能比较好的做局部调试,原因是安卓各个部件之间可能存在依赖关系,比如out/target/product目录下面大部分都需要out/host/的工具支持:
ls -d out/target/*
out/target/common out/target/product
ls -d out/host/*
out/host/common out/host/linux-x86 out/host/windows-x86
还有一些是需要依赖于下面路径的资源
ls -d out/target/product/xxx/system/framework/*.apk
out/target/product/xxx/system/framework/framework-res.apk
(当然,完整编译很耗时,每次切换环境都很麻烦,有精力可以做提取,只要保证基本的依赖组件是完整存在)
然后,以上准备完成,才进入今天的主题。
mmm -B ./frameworks/base/policy/
====
二、 mmm -B ./frameworks/base/policy/
####
cd ./frameworks/base/policy/
mm -B
****
简单介绍一下,局部单编命令:mmm && mm
这两者来源于 ./build/envsetup.sh 脚本中定义的函数 function mmm()和function mm(),此外还有mmma和mma等,功能是类似,做了一定层次依赖的自动编译,由于本人经常碰到失效,故很少使用带a的两个命令;
具体方法可以看注释或使用案例,这里要着重说的是-B参数,它和android没多大关系,是Makefile的功能,使用命令可以看到它:
man make |grep "\-B"
-B, --always-make
info make |grep "\-B"
info: Writing node (*manpages*)make...
info: Done.
-B, --always-make
意思为忽略规则强制编译,和make的快速编译相反,项目很大的话会浪费很大时间;
====
三、 正题
####
mmm -B ./frameworks/base/policy/
****
cd到android工作源码下,然后:
(本人比较赖,不喜欢在多个目录间频繁cd跳,只有在特殊Android.mk才会跑去对应目录下用mm)
mmm -B ./frameworks/base/policy/
有生成dex,但没有正常的out/target/product/xxx/system/framework/android.policy.jar出来:
ll out/target/common/obj/JAVA_LIBRARIES/android.policy_intermediates/classes.dex
-rw-rw-r-- 1 chx chx 293404 Jun 26 20:41 out/target/common/obj/JAVA_LIBRARIES/android.policy_intermediates/classes.dex
ll out/target/product/xxx/system/framework/android.policy.jar
-rw-rw-r-- 1 chx chx 309 Jun 26 20:41 out/target/product/xxx/system/framework/android.policy.jar
正常应该是:
ll out/target/product/xxx/system/framework/android.policy.jar
-rw-rw-r-- 1 chx chx 138588 Aug 21 15:26 out/target/product/xxx/system/framework/android.policy.jar
结果却浪费了很大劲,生成了:
ls -d out/target/product/xxx/system/framework/arm*/boot.*
out/target/product/xxx/system/framework/arm64/boot.art
out/target/product/xxx/system/framework/arm64/boot.oat
out/target/product/xxx/system/framework/arm/boot.art
out/target/product/xxx/system/framework/arm/boot.oat
足足有130M,太庞大了(笔者项目的机器是32+64bit双结构的cpu):
du -sh out/target/product/xxx/system/framework/arm*/boot.*
11M out/target/product/xxx/system/framework/arm64/boot.art
64M out/target/product/xxx/system/framework/arm64/boot.oat
9.8M out/target/product/xxx/system/framework/arm/boot.art
53M out/target/product/xxx/system/framework/arm/boot.oat、
====
四、 art ???
####
oat ???
****
见字思义,art是Lollipop之后用的虚拟机,oat是什么呢?
于是又去重温了一下老罗的ART虚拟机:
Android ART运行时无缝替换Dalvik虚拟机的过程分析
《Android ART运行时无缝替换Dalvik虚拟机的过程分析》 http://blog.csdn.net/luoshengyang/article/details/18006645
说白了,这两者就是加速作用,空间换时间,另外一层也包含了一些基本加密的动作,直接导致的结果是改ROM的人遇见会头疼,不能做局部替换了。
现在要干嘛?当然是能去掉就去掉!
去不掉,那不可能,源码在手,本事看人。
要真的玩不转,就只好删代码走人了……
====
五、 线索: LOCAL_MODULE := android.policy
####
real target: PRODUCT_BOOT_JARS
****
刚刚开始,纠结的是找不到线索,不明白它的编译机制,是如何加入到make的环节进去,如何联合编译成art和oat;
如果性格固执的人,比如我这样的,就开始头大了,不断看代码,从fw到build,很多mk文件都跑遍了,还是蒙圈的状态。
怎么办?改不改?尝试改吧
自己找不到方向了,然后呢?
第一步当然是到网上找,CSDN及其它很多同类网站很多人共享,高手踩坑很多,故此受益的当然是大众;
然后这次没找到,对,就是没找到介绍art和oat的编译开关,老罗那里说的是原理,并没有指出这一步的容器开关在那里配置。
很多人在第一步的时候就
轻松完成目标,或者绞了脑汁糅合代码,实现了需要的东西;然而
很多人也终止在这一步,始终找不到第二步了。
第二步,没办法,死磕代码吧;
其实线索是有的,只是架构太大,一时间理不清,比如policy,它的mk就明显指出了[LOCAL_MODULE := android.policy]的线索是android.policy[NINJA后可能会不同];
安卓的编译架构里,所有跟mk相关的,绝大部分都是在build目录[局部是device&vendor由厂商定制],所以直接找吧 [习惯用grep,sourceInsight/ctags也是一样的]:
grep "android.policy" -nsr ./build/ -C0
./build/target/product/base.mk:24: android.policy \
./build/target/product/core_tiny.mk:97:# android.policy \
./build/target/product/core_minimal.mk:95:# android.policy \
发现三个地方包含了,扩展看一下:
grep "android.policy" -nsr build/ -C13 |grep '= \\'
build/target/product/base.mk-18-PRODUCT_PACKAGES += \
build/target/product/core_tiny.mk-83-PRODUCT_BOOT_JARS := \
build/target/product/core_tiny.mk-100-PRODUCT_SYSTEM_SERVER_JARS := \
build/target/product/core_tiny.mk-106-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
build/target/product/core_tiny.mk-108-PRODUCT_COPY_FILES += \
build/target/product/core_minimal.mk-82-PRODUCT_BOOT_JARS := \
build/target/product/core_minimal.mk-98-PRODUCT_SYSTEM_SERVER_JARS := \
build/target/product/core_minimal.mk-105-PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
build/target/product/core_minimal.mk-107-PRODUCT_COPY_FILES += \
很明显,"97:# android.policy"是归属于"core_tiny.mk-83-PRODUCT_BOOT_JARS := \",
"95:# android.policy \"是归属于"core_minimal.mk-82-PRODUCT_BOOT_JARS := \",
而"base.mk:24: android.policy \" 是归属于"base.mk-18-PRODUCT_PACKAGES += \"这个编译包开关的;
所以我们要找的就是下面这个属性了:
PRODUCT_BOOT_JARS
它包含了很多子集:
vi build/target/product/core_tiny.mk +87
# The order matters
PRODUCT_BOOT_JARS := \
core-libart \
conscrypt \
okhttp \
core-junit \
bouncycastle \
ext \
framework \
telephony-common \
voip-common \
ims-common \
mms-common \
android.policy \
apache-xml \
nullwebview \
vi build/target/product/core_minimal.mk +88
# The order of PRODUCT_BOOT_JARS matters.
PRODUCT_BOOT_JARS := \
core-libart \
conscrypt \
okhttp \
core-junit \
bouncycastle \
ext \
framework \
telephony-common \
voip-common \
ims-common \
mms-common \
android.policy \
apache-xml \
至此,去掉它就是很容易的事情了,直接注释掉或删除就可以了:
====
git st build/target/product/
# On branch master_test
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: build/target/product/core_minimal.mk
# modified: build/target/product/core_tiny.mk
#
no changes added to commit (use "git add" and/or "git commit -a")
####
git diff build/target/product/
diff --git a/build/target/product/core_minimal.mk b/build/target/product/core_minimal.mk
old mode 100644
new mode 100755
index 4c08cb0..938e232
--- a/build/target/product/core_minimal.mk
+++ b/build/target/product/core_minimal.mk
@@ -91,8 +91,8 @@ PRODUCT_BOOT_JARS := \
voip-common \
ims-common \
mms-common \
- android.policy \
apache-xml \
+# android.policy \
# The order of PRODUCT_SYSTEM_SERVER_JARS matters.
PRODUCT_SYSTEM_SERVER_JARS := \
diff --git a/build/target/product/core_tiny.mk b/build/target/product/core_tiny.mk
old mode 100644
new mode 100755
index 9637e34..e58e78c
--- a/build/target/product/core_tiny.mk
+++ b/build/target/product/core_tiny.mk
@@ -92,9 +92,9 @@ PRODUCT_BOOT_JARS := \
voip-common \
ims-common \
mms-common \
- android.policy \
apache-xml \
nullwebview \
+# android.policy \
# The order of PRODUCT_SYSTEM_SERVER_JARS matters.
PRODUCT_SYSTEM_SERVER_JARS := \
****
这个改动需要编译两个地方,一个是去掉的,一个是任意子项,以生成两个目标:
1.
out/target/product/xxx/system/framework/arm/boot.art
out/target/product/xxx/system/framework/arm/boot.oat
2.
ll out/target/product/xxx/system/framework/android.policy.jar
-rw-rw-r-- 1 chx chx 138588 Aug 21 15:26 out/target/product/xxx/system/framework/android.policy.jar
再不是309字节的版本。
====
####
****
平时改的问题比较杂,都很少写记录,年岁越来越多,开始忘了很多东西,还是要保持烂笔头。
The end.
====
####
****
|