减小差分包文档分析

深入分析Android (build/core/*.mk脚本) 文档简要整理Android的make脚本的内容。以供备忘和参考。 1. Build Layers Build Layers描述的是产品的硬件配置情况,据此make时选择不同的配置和模块。按照从上到下的顺序,Build Layer分成4层。 Layer sample Note A... 阅读详情

概述
对于谷歌文档关于减小差分包大小,在Android代码中进行了确认,大致分为以下三部分,说明修改思路和
具体修改内容,并给出相应总结。 源:https://source.android.com/devices/tech/ota/reduce_size
一、编译初始化过程中处理文件排序
二、编译生成文件(jar,zip,lib.so,apk)的内嵌时间戳处理
三、其他生成镜像时处理(两个被弃用的方法,简单说明)

一、编译初始化文件排序
1、简单说明编译初始化过程
make -j8
执行make命令会执行code/mode/Makefile文件
include build/core/main.mk
main.mk文件里定义了整个Android的编译关系,它主要引入了下列几个重要的mk文件:
include $(BUILD_SYSTEM)/config.mk
根据board配置信息和host配置参数定义编译时用到的变量
include $(BUILD_SYSTEM)/cleanbuild.mk 定义删除编译结果的函数和目标
include $(BUILD_SYSTEM)/definitions.mk 定义了编译过程中通用的变量和宏(我们主要跟踪对象)
执行make/core/Makefile,编译镜像文件

2、definitions.mk文件说明

该文件里定义了Android.mk里的通用的字段,我们编译androi.mk编译APK或者lib,有一些方法提取 成通用放在了definitions.mk文件里边,例如

获取包含Android.mk的目录路径LOCAL_PATH := $(call my-dir)  

获取编译目录下的全部makefile文件include $(call all-makefiles-under,$(LOCAL_PATH))

编译target需要使用到的source源文件,.cpp;.c文件 LOCAL_SRC_FILES := $(call all-subdir-cpp-files) $(call all-subdir-c-files)

3、举例说明修正文件排序问题
以call all-subdir-c-files和call all-subdir-java-files为例,获取当前目录下的全部.cpp文件和.java文件
最好在definition.mk文件里都走了同一个宏控,因为其实相同的find shell命令,传入不同的后缀即可
其中patsubst属于makefile文件中放通配符,通配符一共有三种
1、wildcard : 扩展通配符
2、notdir : 去除路径
3、patsubst :替换通配符
define find-files-in-subdirs
$(patsubst ./%,%, $(shell cd $(1) ; find -L $(3) -name $(2) -and -not -name ".*") \)
endef
find命令是没有顺序的,那么我们可以加入sort方法,让输出变成有序,变更代码如下
define find-files-in-subdirs
$(sort $(patsubst ./%,%, $(shell cd $(1) ; find -L $(3) -name $(2) -and -not -name ".*") ))
endef
我们把这句话在Android.mk中加入做一个小测试如下,就可以发现文件展开结果的差别,有sort的文件将有序:

4、交给底层编译器的路径问题
因.cpp .cc文件交给GCC编译器编译时,会转化为.o文件,如果新老版本编译在不同编译环境,不同电脑,
可能交给编译器的文件路径而产生变化,所以使用静态路径PWD=/proc/self/cwd替换之前的绝对路径。
主要运用在了difinition.mk中,加入RELATIVE_PWD := PWD=/proc/self/cwd
define transform-cpp-to-o
@echo "$($(PRIVATE_PREFIX)DISPLAY) $(PRIVATE_ARM_MODE) C++: $(PRIVATE_MODULE) <= $<"
@mkdir -p $(dir $@)
$(if $(PRIVATE_TIDY_CHECKS),$(clang-tidy-cpp))
$(hide) $(RELATIVE_PWD) $(PRIVATE_CXX) \
$(transform-cpp-to-o-compiler-args) \
-MD -MF $(patsubst %.o,%.d,$@) -o $@ $<
endef
总结:
主要优化思路执行shell-find和通配符wildcard,notdir,patsubst时加入sort,使拿到的文件都会有顺序,但是
实际对比来说,编译文件的有序其实并不会对输出结果造成影响,这一部分的修改只会让代码编译时比较规整

二、内嵌时间戳处理
1、加入Android 7.0 开启了 -Werror=date-time
大致查了一些资料,-werror应该是GCC编译器的规则,且在Android9.0 soong(8.0之后新的编译方式)
中也有加入
GCC 4.9 and newer have a new warning -Wdate-time, which warns on any use
of __DATE__, __TIME__, or __TIMESTAMP__, which would make the build
non-deterministic. Now that the kernel does not use any of those
macros, turn on -Werror=date-time if available, to keep it that way.
加入该控制后,代码中不能出现 __DATE__, __TIME__, or __TIMESTAMP__相关的字符或者打印,测试后发现
在.cpp中加入确实时会编译报错
本身去除时间戳是为了避免生成文件的不必要变化,那么这就引入一个问题,在不能加入时间戳的情况下,
我们如何处理jar,zip,lib,嵌入编译时间呢,下面我们作下解读

1、lib文件处理
以external/libchrome为例
android.bp中引入了"libcutils",该库中有获取prop属性的方法,
通过propery_get方法,可以读取到ro.build.date最后返回的integral_build_time也就是ro.build.date

TODO:这里的修改不能得到完全理解,如果按照之前的const char kDateTime[] = "Sep 02 2008 08:00:00 PST";那生成的两个lib应该时一样的 按照目前读取编译时间怎么会使生成结果相同呢

2、zip ,jar文件处理-ziptime
由于jar本身也属于一种压缩格式,所以两个被归为一类处理;
这里引入一个Android编译时用到的工具./make/tools/ziptime
原本介绍:
ziptime -- zip timestamp tool
usage: ziptime file.zip
file.zip is an existing Zip archive to rewrite
This tools replaces the timestamps in the zip headers with a static time
(Jan 1 2008). The extra fields are not changed, so you'll need to use the
-X option to zip so that it doesn't create the 'universal time' extra.
大致解读为,所有的zip.jar文件最后生成时内部文件时间标记为2008年1月1日00:00
这也时为什么中间包中看里面的压缩时间为2008年0101的原因
解压了一些jar包,以及中间文件,发现都是在这个时间,而core/Makefile中并没有对压缩target文件单独
添加ziptime,所以这是编译时全局工具,所有的压缩文件都会使用该时间


3、sign签名apk和升级包处理
为了保证签名后的内嵌时间一致,在build/tools/signapk/src/com/android/signapk/SignApk.java中加入

// Set all ZIP file timestamps to Jan 1 2009 00:00:00.
long timestamp = 1230768000000L;
// The Java ZipEntry API we're using converts milliseconds since epoch into MS-DOS
// timestamp using the current timezone. We thus adjust the milliseconds since epoch
// value to end up with MS-DOS timestamp of Jan 1 2009 00:00:00.
timestamp -= TimeZone.getDefault().getOffset(timestamp);

设置timestamp为2009年1月1号00:00,SignApk.signWholeFile和signFile中加入该时间timestamp
这样涉及到签名的APK和升级包都为该内嵌时间
这也就是我们查看升级包时间时,内部显示文件时间为2009年,如果我们解压平台签名APK的话里面也是2009年

4、去除编译APK中的BUILD_NUMBER
去除app_version中的时间戳字段BUILD_NUMBER
ifneq "" "$(filter eng.%,$(BUILD_NUMBER))"
git_hash := $(shell git --git-dir $(LOCAL_PATH)/.git log -n 1 --pretty=format:%h)
date_string := $$(date +%m%d%y_%H%M%S)
变更version_name为:
version_name_package := $(base_version_major).$(base_version_minor).$(base_version_build)
这样如果APK没有修改的话,不会因为版本号差异而产生patch
总结:
内嵌时间戳的问题处理,将会减少一些文件不必要的差异化存在,降低一些patch的生成,
对减小差分包有一定的作用。

三、其他生成镜像时处理

这个方面中介绍的两个方面都是在7.0后没有什么作用的,不过可以简单了解下
1、target_files_diff.py
查询代码后,该文件现在只用于打印metadata 元数据的对比信息
在ota_from_target_files.py中以--log_diff 做包加入后会运行

如果做包的命令中有--log_diff 会调用recursivediff方法

最后会输出log信息,为ota_target_file.zip/META 中所有文件 source和target的对比信息

2、system_base_fs_file
在文档中提到的理论make_ext4fs 会接受可选的 -d base_fs ,这样生成system.img的时候会用到老版本的
system.map,尽量把对应文件放在相对应的块上,这样确实不会减少差分包的大小,因为块的差异数量是
没有变化的,但是确实会减少升级过程中move的情况出现,实际来说查询7.0到9.0的代码,并不存在这个功能
首先大概说下make otapackage过程中生成system.img的大概过程
makefile中定义了
define generate-userimage-prop-dictionary 会定义给一部分字段,这些字段会追加到
system_image_info.txt和misc_info.txt中,代码如下
$(call generate-userimage-prop-dictionary, $(systemimage_intermediates)/system_image_info.txt, \
skip_fsck=true)
$(call generate-userimage-prop-dictionary, $(zip_root)/META/misc_info.txt)
make ota过程中会通过add_img_to_target_files最后调用build_image,py重新生成system.img
build/make/tools/releasetools/add_img_to_target_files -a -v -p $(HOST_OUT) $(zip_root)
而生成的规则都是在misc_info.txt中定义的
为什么说没有这个功能的原因
$(if $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_BASE_FS_PATH),
$(hide) echo "system_base_fs_file=$(PRODUCTS.$(INTERNAL_PRODUCT).
PRODUCT_SYSTEM_BASE_FS_PATH)" >> $(1))
define generate-userimage-prop-dictionary 中确实定义了该字段,但是后续misc_info.txt文件中并没有
system_base_fs_file相关的定义,本身PRODUCT_SYSTEM_BASE_FS_PATH应该指向一个文件路径
而代码中也没有查到,

最后执行mkuserimg_mke2fs.sh 也有没有-d base_fs选项,编译system.img log如下

四、总结

 以上对文档内容划分并进行了解读,因文档比较老,一些方法或者文件已经不在使用,而且基本涉及都是编译生成 文件阶段,对于OTA升级包减小其实没有太大的帮助,不过可以更好的理解一些编译相关的机制。  。

微信小程序包大小超过2M的解决方法—分包加载 小程序的包被限制在2M以下, 超出的时候点击预览, 发现报错 阅读详情

相关推荐

uniapp 小程序分包实战:优化启动速度与资源管理

本文详细介绍了uniapp小程序分包的实战技巧,包括分包配置、静态资源管理和预加载策略,帮助开发者优化启动速度与资源管理。通过合理分包,主包体积可显著减小,冷启动时间缩短30%-50%,特别适合功能模块多的电商类小程序。

weixin_30631587的博客 473

深入分析android (build/core/*.mk脚本),全面深入分析Android.mk (build/core/*.mk脚本)

或CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f build/core/config.mk dumpvar-abs-第一种形式,返回varName的值。第二种形式,返回varName的值,前缀上路径。考虑到android脚本中广泛使用':=’的变量定义方法,因此,基本上只能显示dumpvar.mk之前定义的变量值。LOCAL_xxxx的...

weixin_35573869的博客 627

JavaScript性能优化:全链路性能优化策略

JavaScript性能优化是提升Web应用质量的核心要素,直接影响用户体验与业务成果。研究表明,页面加载延迟1秒可能导致转化率下降7%。高效的JavaScript执行能减少主线程阻塞,避免动画卡顿或操作延迟,尤其在移动端低性能设备上更为关键。优化内存管理与减少冗余计算可降低浏览器资源消耗,防止因内存泄漏导致的崩溃,提升应用稳定性。在竞争激烈的互联网环境中,性能优势已成为产品差异化的关键因素,直接影响用户留存与商业价值。因此,性能优化应作为开发全周期的核心实践,而非事后补救措施。

weixin_49707375的博客 1271

Makefile编写及一个简单的Makefile架构实现

本文通过总结makefile的相关使用,并将以前大型项目中用到的Makefile简单的记录下,以便以后快速应用: Makefile常用命令 GCC/G++常用编译参数 简单Makefile框架实现 Makefile常用命令 make Makefile/makefile/GNUMakefile 当Makefile名字不是上述三个名字时,需要加-f 去编译,如xxx.mk...

ChrisMM 3166

Android OTA 升级实战指南:从原理到实现

本文详细解析了Android OTA升级的原理与实现方法,包括AB升级与Recovery升级的机制对比、OTA升级包制作流程以及应用层升级功能的实现。通过实战案例和常见问题排查指南,帮助开发者掌握Android系统无线升级技术,提升设备维护效率。

weixin_42652674的博客 199

【5G核心网】Packet Forwarding Model 数据包转发模型

CP 通过建立,修改,删除 PFCP 会话上下文,以及通过为每个 PFCP 会话赏析哪问提供 PDR FAR QER URR BAR,来控制 UP 面的数据包处理。 每一个 PDR 都包含 PDI(Packet Detection Information,包探测信息),一个或多个字段,与输入数据包进行匹配,并可能与以下规则相关联,从而提供了适用于与 PDI 匹配的数据包的指令集: - One FAR(包含了处理数据包的相关指令) an Apply Act...

zhonglinzhang 1万+

Android编译系统详解(三)——编译流程详解

http://www.cloudchou.com/android/post-276.html 1.概述 编译Android的第三步是使用mka命令进行编译,当然我们也可以使用make –j4,但是推荐使用mka命令。因为mka将自动计算-j选项的数字,让我们不用纠结这个数字到底是多少(这个数字其实就是所有cpu的核心数)。在编译时我们可以带上我们需要编译的目标,假设

thinkinwm的专栏 3741

c++界面开发入门

c++界面开发 DialogBox MessageBox

jiaodou2的博客 6517

android make脚本解析,Android make脚本简记

或CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core make -f build/core/config.mk dumpvar-abs-第一种形式,返回varName的值。第二种形式,返回varName的值,前缀上路径。考虑到android脚本中广泛使用':=’的变量定义方法,因此,基本上只能显示dumpvar.mk之前定义的变量值。LOCAL_xxxx的...

weixin_33891841的博客 466

使用Java实现CRC16 MODBUS 格式校验

CRC16校验,测试如下 String str = "a5 98 03 00 00 5f c6 0f 7c 40 78 06 09 46 dc 6e db 00 16 3e 12 5c 98 00 19 98 0e 10 03 06 09 46 dc 6e db 03 0b bf 5f c6 0f 7c 43 bd b9 61 ee 96 76 99"; 校验规则: /** * CRC16_CCITT:多项式x16+x12+x5+1(0x1021),初始值0x0000,低位在前,高位在后,结

weixin_45063710的博客 1315

全国各省份影像下载地址(11级别)

cesium中使用urltemplate加载,leaflet中使用tile加载,具体加载有问题可以给我留言。

资深三维GIS开发 5148

小程序 (Taro) 减小包体积:压缩代码以及分包的实现

用Taro做的小程序快要完工了,奈何每个包的大小只能为2M,总大小不能超过8M。所以就需要压缩代码和分包了。由于这是我第一个小程序的项目,所以我把我踩到的坑详细讲一下,欢迎大家来分享宝贵意见以及补充~ 压缩代码: plugins.uglify Taro官方给出的配置项,用来配置 UgligyJS 工具,设置打包过程中的 JS 代码压缩。可以通过 plugins.uglify.enable 来设置是...

weixin_43582313的博客 9489

【WLAN】【基础知识】WIFI那些事儿之信道和频谱(涵盖2.4G、5G、6G,全网最全)

- 从事WIFI相关开发或测试工作,经常要和信道、频宽、频率等打交道,本文仅将平时涉及的2.4G、5G、6G的信道、频宽、频率等做一总结。 - 一图胜万言,本文汇总了工作中经常用到的频谱图,保证全网最全!!! - 本博客地址,https://blog.csdn.net/qxhgd,欢迎各位关注,转发请注明出处。

一介草民,只为生活。 1万+

2024 最新基于Uni-app和Vue3实现微信小程序分包,并且主包调用分包页面作为组件加载,包括优化预加载-详细教程和使用

然后在创建子级目录目录结构如图所示第一步:配置manifest.json文件。

3861

无需SLAM建图,直接生成Gazebo仿真环境的二维代价地图的功能包pgm_map_creator适配ROS Noetic编译报错及解决方法

在ROS Noetic中,使用`pgm_map_creator`功能包直接生成Gazebo仿真环境的二维代价地图时,可能会遇到各种编译和运行错误。本篇博客详细解析了在适配ROS Noetic过程中常见的报错及其解决方法,包括Boost文件结构更新、C++版本兼容性、Gazebo函数名变更、链接库缺失以及protobuf文件加载错误。通过逐步排查和修改,如更换头文件路径、调整C++标准、更新CMakeLists.txt文件等,成功解决了这些问题,使得`pgm_map_creator`功能包能够顺利编译和运行。

慕羽★的博客 2261

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【小程序分包】小程序包大于2M,来这教你分包啊

小程序超出大小,分包加载步骤 1.查看项目结构 2.分析主包大小 3.查阅参考文档 4.结构调整 5.修改pages.json

JavaDog程序狗 2074

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

uniapp小程序分包(uniapp分布)都是干货

首先说分包 uniapp分包的方法在开放文档里有,有一定基础的小伙伴还是可以看懂的 我是链接 下面是我在开发中用到的分包 首先 我们在根目录下创建一个pagesB文件夹,用来放置需要分包的页面 下一步是把比较大的文件直接拉过去,pages里就没有这个文件了,然后配置路由 "subPackages": [{ "root": "pagesB", //文件夹名称, pages文件夹同级新建一个就行 "pages": [ { "path" : "line_otem_detail/li

weixin_45811884的博客 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

uview放在主包太大,如何放到分包,并且可以在主包正常使用

解决uview放主包太大,直接放到分包里面,并主、分包正常使用

Leungsintin的博客 3325

Alita分包策略:如何一键实现小程序自动分包

小程序体积优化是开发者面临的重要挑战,而Alita作为一套把React Native代码转换成微信小程序代码的转换引擎工具,提供了简单高效的自动分包解决方案。通过Alita的一键自动分包功能,开发者可以轻松突破小程序体积限制,提升应用性能。 ## 为什么需要小程序分包? 微信小程序对体积有严格限制,主包不能超过2M。当应用功能逐渐丰富,体积很容易超标。此外,为了减少首屏加载时间,也需要将非核心

gitblog_01170的博客 780

微信小程序-使用 vant-weapp 之后的分包优化

背景 在开发中引入了 vant-weapp 导致项目包过大,真机调试不了,也上传不了,所以只能分包加载了。 实现 首先就是根据官方文档进行分包 但是有可能包体积还是过大,这时候只能进入到vant-weapp库的目录下,删除不必要的组件了。 我们在用npm安装vant-weapp构建后会生成两个文件夹 这两个文件的区别,官网也说明了:原理介绍 node_modules 目录不会参与编译、上传和打包中 miniprogram_npm 目录,里面会存放构建打包后的 npm 包,也就是小程序真正使用的 np

龙衣 4459

微信小程序分包

微信小程序分包实践

weixin_40496794的博客 1894

uni-app微信小程序分包处理

场景 由于微信小程序规定不能超过2M,在做了精简优化代码之后还是太大了,无法上传代码怎么办?使用官方支持的分包来解决。 官方文档:https://uniapp.dcloud.io/collocation/pages?id=subpackages subPackages里的pages的路径是root下的相对路径,不是全路径。 微信小程序每个分包的大小是2M,总体积一共不能超过16M。 百度小程序每个分包的大小是2M,总体积一共不能超过8M。 支付宝小程序每个分包的大小是2M,总体积一共不能...

weixin_42543235的博客 3164

基于uniapp的小程序 分包步骤

最近在用uniapp写小程序,加的页面和功能有点多,发现。。。上传失败,超过了2M,只能进行分包了。 1.uniapp 给出了**官方的分包的文档** 2.言归正传,开始进行分包。 2.1 建立和page文件加同级的分包文件夹 名称自己定 在分包的这个文件加下面把想分出的文件放在这里 2.2 在manifest.json文件中在微信小程序配置 optimization 2.3 在pages.json文件中,进行配置 建立和 pages同级的数组,然后配置subPackages 以及root是配置和你前面

anjignren的博客 686

微信小程序使用分包

文章目录使用分包的配置FAQ主包跳转到分包页面分包使用主包中的文件 小程序的包大小限制为 2M,一不小心就超出去了,对于我们开发而言,十分的不方便,就需要我们尽可能的将一些静态资源放到服务器上来减小包大小(一般为图片),但随着第三方框架的引入,业务代码依旧很容易触及小程序的上限,故我们需要采取分包的方式来继续开发 参考文章:微信小程序—分包操作、微信小程序分包相关文档 目前小程序分包大小有以下限制: 整个小程序所有分包大小不超过 20M 单个分包/主包大小不能超过 2M 使用分包的配置 app.j

RealizeInnerSelf丶 856

Taro微信小程序上线相关(包括分包操作)

cnpm run dev:weapp //运行程序 cnpm run build:weapp //打包程序 使用分包|微信开发文档 不知道命令咋写的时候,就看package.json,上面对指令使用有详细的解释。 一定先把代码打包才上传代码,不是代码太大,是你没有build。 弄了一上午学会了subPackages分包,但代码确实没问题。。。。。 ...

比起未来可期,我更喜欢如约而至 1151

uniapp之小程序分包操作

本文介绍了小程序分包操作流程:当主包超过2M限制时,需进行分包处理。以uniapp为例,首先分析项目结构,通过微信开发者工具查看主包大小;然后新建subPages_A和subPages_B子包,将原pages下页面移入子包;接着修改pages.json配置文件,在subPackages中配置子包路径;最后调整代码中的页面跳转路径。完成分包后主包大小从399.8KB降至326.0KB,成功实现分包优化。关键点包括正确配置subPackages、调整页面路径以及注意静态资源优化。

coldriversnow的专栏 152
上一篇: Android9.0 vendor分区整包升级
下一篇: 二、Android BCB的作用
李标标
博客等级 码龄11年 124粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值