【干货】Android系统定制基础篇:第四部分-Android二次构建

news2024/9/24 5:30:45

背景

有时我们需要使用同一套Android源码编译生成各种差异化产品固件,比如:A产品、B产品、C产品,各产品之间大部分功能是相同的,仅个别功能定义上有差别。

方法一 Android默认的做法是在源码 device 目录下增加A、B、C产品,差异化通过 makefile 配置区分。比如:预装哪些APK,使用哪个开机动画。但这种方法有以下几个缺点:
● 每种产品都需要单独编译整个Android源码,而Android源码编译需要耗费较长时间。
● 无法决定 kernel 的差异,比如:A、B、C产品它们的硬件上有差异,需要分别编译不同的dts文件,这种方式就无法实现。
● 如果A、B、C产品之间的差异非常小,比如仅仅是开机动画的不同,也增加一个device来区分,也需要单独编译整个Android源码,就有点太耗费资源。

方法二 通过git分支来管理,每个产品单独拉一个git分支,这种方式适应于源码差异非常大,并且无法兼容,相互之间存在冲突的情况。像上面所述,如果A、B、C产品之间仅仅是开机动画的不同,也通过单独git分支来维护,自然就不妥了。另外,一旦产品数量多起来,维护各种git分支就变的相当困难。

方法三 将Android源码与产品解耦,Android源码只负责各种基础功能,产品相关的差异配置全部提取到另外一个仓库。我们在这里暂且约定Android源码为『Android仓库』,产品配置的仓库为『产品仓库』(这里的仓库指git仓库,可以理解为存在两个git仓库,一个管理Android源码,一个管理产品配置)。

我们将『Android仓库』编译后生成的相关文件打包,将其复制到特定路径下,称之为『二次开发包』。『产品仓库』中集成了二次打包相关脚步,当需要生成特定产品固件时,将『二次开发包』复制到『产品仓库』指定路径下,脚本会解压『二次开发包』并将特定产品的所有配置合入其中,从而生产最终产品固件。

这样一来,A、B、C产品共用同一份『二次开发包』,只要Android源码没有修改,就不用重新编译Android源码,而只需要执行『产品仓库』中的二次打包脚步,这往往只需要几分钟就可以打包完成,大大提高了发布产品固件的速度。

下面用一张简单的示意图来描述整个过程:
在这里插入图片描述上面示意图说明『Adroid仓库』默认支持A、B、C三个功能,通过『产品仓库』进行二次打包后,支持了A、B、C、D四项功能。

文本要讲的就是上面的『方法三』,下面开始详细说明实现细节。

项目介绍

项目 Android-SecBuild 基于 方法三 在rockchip平台上实现了二次构建方案。
项目包含『Android仓库』的构建脚本和『产品仓库』的构建脚本,目录结构如下:

├─Android							Android仓库
│  ├─build							Android构建脚本
│  ├─device							device目录
│  │  └─DEFAULT					每个目录代表一个device,里面包含config.ini用于配置uboot config、kernel config、dts
│  └─outputs						构建结果
│
└─Product							产品仓库
    ├─build							二次构建脚本
    ├─outputs						构建结果				
    ├─platform					将二次开发包拷贝至此目录
    └─product						产品目录(里面每一个目录代表一个产品)
        ├─DEFAULT				DEFAULT产品
        └─PARENT				PARENT产品

Android仓库

集成构建脚本
将 Android-SecBuild 项目中『Android』目录拷贝到Android源码根目录下,并重命名为『secbuild』,如下:

├─Android
  ......
  ├─external
  ├─frameworks
  ├─hardware
  ├─kernel
  ├─uboot
  ├─pakcages
  ├─system
  ......
  └─secbuild						新增
    ├─build
    |   ......
    |   ├─build.sh
    |   ├─full_build.sh
    |   ├─pack.sh
		|		......
    ├─device
    |   ├─DEFAULT
    |        └config.ini
    └─outputs

build 目录下为构建脚本,里面包含三个主要脚本(其它脚本及工具是rockchip平台相关的,请根据平台确定要否需要),分别为:full_build.sh、build.sh、pack.sh。
● full_build.sh 负责调用build.sh和pack.sh。
● build.sh 编译Android源码。
● pack.sh 将Android源码编译产物和二次打包所需工具打包成二次开发包。

device/DEFAULT 下config.ini文件用于配置uboot config、kernel config和dts,内容如下:

# u-boot config
UBOOT_DEFCONFIG=default_defconfig

# kernel config
KERNEL_DEFCONFIG=default_defconfig

# kernel dts
KERNEL_DTS=default_dts

outputs 目录为构建结果,包含Android源码编译生成的各种img和二次开发包等。

生成二次开发包
执行 secbuild/build/full_build.sh 脚本编译Android系统并打包二次开发包。

./full_build.sh -t target -d device

target Android target
device secbuild/device/下目录名
例子:

./full_build.sh -t rk3288 -d DEFAULT

执行完成后将在outputs目录下生成二次开发包。
在这里插入图片描述二次开发包
命名
二次开发包的命名规则为

rom_分支_版本号_commit-id_日期.tar.gz
其中版本号的命名规则为:

[平台][Android版本].主版本号.commit计数
例子:

rom_master_1381.1.443_bcccadf_2020-04-24.tar.gz
      |    | |  |  |     |
      |    | |  |  |     最新commit-id
      |    | |  |  commit计数(比如提交了100次,值就是100|    | |  主版本
      |    | Android版本(51: Android 5.1 60: Android 6.0 71: Android 7.1 81: Android 8.1|    平台(比如:11: RK3128 12: RK3368 13:RK3288)
      git分支

内容:

rom_master_1381.1.443_bcccadf_2020-04-24.tar.gz
├─rom_git_verson.prop				记录git仓库地址和最新Commit id
├─image											Android源码编译生成的各种image
├─target_files.zip					Android target files,里面包含Android各分区原始文件
└─tools											二次打包时需要的各种工具
    ├─bin
    ├─framework
    ├─lib64
    └─releasetools

其中 target_files.zip 为二次打包的核心,这里面包含Android各分区原始文件。因此,可以通过工具对其进行重新打包生成各分区image文件。内容如下:

target_file.zip
  ├─BOOT  
  ├─DATA  
  ├─IMAGES  
  ├─META  
  ├─OEM  
  ├─OTA  
  ├─RECOVERY  
  ├─SYSTEM 
  ├─trust.img*  
  ├─uboot.img*  
  └─VENDOR

产品仓库

将 Android-SecBuild 项目中『Product』单独新建一个git仓库,并提交。
文件解释

Product
├─product													产品目录
|    ├─PARENT												PARENT产品
|    |   ├─config.ini									产品配置
|    |   ├─default.dtb								dtb文件(配置主板硬件特性)
|    |   └logo.bmp										开机logo
|    ├─DEFAULT											DEFAULT产品
|    |    ├─config.ini								产品配置
|    |    ├─default.dtb								dtb文件(配置主板硬件特性)
|    |    ├─logo.bmp									开机logo
|    |    ├─system										system分区(拷贝至android system分区,同名替换)
|    |    |   ├─media
|    |    |   |   └bootanimation.zip	替换开机动画
|    |    |   ├─app
|    |    |   |  ├─SougouIME					内置搜索输入法
|    |    |   |  |     ├─SougouIME.apk
|    |    |   |  |     ├─lib
|    |    |   |  |     |  ├─arm
|    |    |   |  |     |  |  └libsogouime.so
├─platform												二次开发包将拷贝至此目录下
├─outputs													构建结果(最终image文件)
├─build														构建脚本									
|   ......
|   ├─mkimage_o.sh									生成各分区image(平台相关:rockchip)
|   ├─mkproduct.sh									主脚本,解压二次开发包,解析config.ini,替换文件,调用mkimage_o.sh、mkupdate_image.sh、mkupdate_zip.sh
|   ├─mkupdate_img.sh								生成rockchip update.img烧录包(平台相关:rockchip)
|   ├─mkupdate_zip_o.sh							生成ota升级包

mkproduct.sh
● 解压二次开发包。
● 替换各分区文件(system、vendor、oem、root、recovery等)。
● 解析platform目录下apk文件并内置。
● 解析 config.ini 配置,并替换属性、删除文件。
● 调用 mkimage_o.sh 生成各分区image。
● 调用 mkupdate_image.sh 生成rockchip update.img烧录包。
● 调用 mkupdate_zip_o.sh 生成ota升级包。
mkimage_o.sh
● 生成各分区image(平台相关:rockchip)。
mkupdate_img.sh
● 生成rockchip update.img烧录包(平台相关:rockchip)。
mkupdate_zip_o.sh
● 生成ota升级包。

二次打包

将『Android仓库』中构建生成的『二次开发包』拷贝到 platform 目录下。
执行 build/mkproduct.sh 脚本将会解压二次开发包,合入产品配置,并二次打包生成最终固件。

./mkproduct.sh product

product 产品名(product/路径下目录名)
例子:

./mkproduct.sh DEFAULT

执行完成后将在outputs目录下生成最终固件,如下:

rk3288_update_DEFAULT_v1.0.1(2)_ce1c332_2020-04-26.img
   |            |        |   |     |
   |            |        |   |     git最新commit-id
   |            |        |   build号
	 |            |        版本号
   |            产品
   target(芯片平台)

在这里插入图片描述产品配置
典型的产品配置目录结构如下:

├─DEFAULT											DEFAULT产品
|    ├─config.ini								产品配置
|    ├─default.dtb							dtb文件(配置主板硬件特性)
|    ├─logo.bmp									开机logo
|    ├─system										system分区(拷贝至android system分区,同名替换)
|    |   ├─media
|    |   |   └bootanimation.zip	替换开机动画
|    |   ├─app
|    |   |  ├─SougouIME					内置搜索输入法
|    |   |  |     ├─SougouIME.apk
|    |   |  |     ├─lib
|    |   |  |     |  ├─arm
|    |   |  |     |  |  └libsogouime.so

config.ini

config.ini 支持三个关键字:EXTENDS、PROP、DEL,它们各位的含义如下:

# 继承,关键字:EXTEND,值为另一个产品。
# 用于减少重复文件,减小仓库大小,公共文件只需要在父产品中放置一份即可。
EXTENDS=PARENT

# 配置属性,关键字:PROP,值为属性名@属性值,@前为属性名,@后的属性值
PROP=ro.product.name@default

# 删除文件,关键字:DEL,值为文件路径
DEL=SYSTEM/app/Launcher3

注意 EXTENDS 关键字只可以使用一次,PROP 和 DEL 可以无限使用。
例子

# 继承,关键字:EXTEND,值为另一个产品。
# 用于减少重复文件,减小仓库大小,公共文件只需要在父产品中放置一份即可。
#EXTENDS=RUNNING

# 配置属性,关键字:PROP,值为属性名@属性值,@前为属性名,@后的属性值
PROP=ro.product.name@default
PROP=ro.build.product@default
PROP=ro.product.brand@google
PROP=ro.product.device@default
PROP=ro.product.model@default
PROP=ro.product.board@rk30sdk
PROP=persist.sys.rotate.enable@0
PROP=persist.sys.sleep.enable@0

# 删除文件,关键字:DEL,值为文件路径
DEL=SYSTEM/app/Launcher3
DEL=SYSTEM/app/WallpaperPicker
DEL=SYSTEM/app/SoundRecorder

dtb
在android源码中编译对应主板的dts生成dtb文件,将其拷贝到具体产品根目录下,用于配置主板硬件差异。
logo.bmp
产品开机动画。
system
二次打包会将此目录下所有文件拷贝至android system分区,已存在的文件替换,不存在的文件增加。同理,还可以增加 vendor、oem、root、recovery 等分区,都是按路径替换文件。

因此,通过dtb可以配置硬件差异,通过属性配置功能差异,通过文件删除替换来内置或精简系统。

自动构建

将上述二次构建的框架与持续集成平台 Jenkins 结合,达到自动构建的目的。
Jenkins 配置『Android仓库』构建。

#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
export USER=$(whoami)
export HOME=/home/tomcat

rm out -rf
./full_build.sh -t rk3288 -d DEFAULT

在这里插入图片描述Jenkins 配置『产品仓库』构建。

#!/bin/bash
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
rm -rf platform/*
cp -vf ../AndroidAutoUpgrade-Baidu/app/build/outputs/apk/release/AutoUpgrade*.apk  ./platform/RomUpgrade.apk || exit $1
cp -vf ../AndroidStressTest/app/build/outputs/apk/release/AndroidStressTest*.apk  ./platform/AndroidStressTest.apk || exit $1
cp -vf ../AndroidX/app/build/outputs/apk/release/AndroidX*.apk  ./platform/AndroidX.apk || exit $1
cp -vf ../RK3288_ROM_DEFAULT/secbuild/outputs/rom_*.tar.gz ./platform || exit $1

cd build
./mkproduct.sh LS328-DEFAULT
cd -

在这里插入图片描述构建后生成产品固件。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/658464.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三个领域的微调模型;Meta推出新的生成式AI模型Voicebox

🦉 AI新闻 🚀 Meta推出新的生成式AI模型Voicebox,可执行音频编辑、采样、风格化等语音生成任务 摘要:Meta继推出ImageBind之后,于今天再次推出了全新的生成式AI模型Voicebox。该模型帮助创作者执行音频编辑、采样和风…

2023年6月最新|大屏可视化配置

大屏可视化配置 运行环境:VScode 一、可视化适配 大屏下显示一般都是16:9尺寸 1920*1080 ,做适配也就是在这个比例的基础上进行的 方案一:打开VSCode终端,下载flexible 1、选中要运行的文件,右键–>【在集成终…

使用Apache ShardingSphere简答实现水平分表

1 简介 Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。 官方网站 https://shardingsphere.apache.org/document/current/cn/overview/2 创建…

【算法题刷题笔记】华为OD机试 - 农场施肥

样例一: 5 7 5 7 9 15 10>> 9样例二: 3 1 2 3 4>> -1解题思路 题目大概意思: 给你N个数, 还有一个数M, 让你求K, 进行M次减K操作, 令这N个数都小于等于0。 思路: 利用…

frp配置多端口内网穿透?frp多端口怎么配置?

FRP内网穿透应用场景:本地Web服务外网访问、本地开发微信、本地联调支付宝\微信支付、TCP/UDP端口转发 在本机开发好的网站想让客户测试不在需要上传到服务器上面,使用FRP内外网穿透轻松解决;微信开发也不需要在上传到服务器,使用…

拒绝服务攻击

目录 一、初始DOS攻击与防御 1.1 DOS攻击概念 1.2 DOS攻击原因 1.2.1 内因 1.2.2 外因 1.3 DOS攻击原理 1.4 DOS攻击方法 二、DOS常见攻击技术 2.1 SYN Flood 2.1.1 基本思想 2.1.2 方法 2.1.3 防御措施 2.2 ICMP Flood 2.2.1 Smurf Flood 2.2.2 Ping of Death …

【微信小程序开发】第 10 课 - WXML 模版语法 - 数据绑定

欢迎来到博主 Apeiron 的博客,祝您旅程愉快 ! 时止则止,时行则行。动静不失其时,其道光明。 目录 1、缘起 2、数据绑定 2.1、绑定的基本规则 2.2、Mustache 语法的格式 2.2.1动态绑定内容 2.2.2动态绑定属性 2.2.3三元运…

Qqis中采用栅格工具生成XYZ瓦片(目录)简介

目录 前言 一、Qgis的相关功能 1、数据准备 2、将两个xyz图源添加到图层 二、Qgis栅格工具生成 1、生成xyz图块工具在哪里 2、生成xyz图块怎么用 3、下载结果 4、Leaflet加载离线瓦块 总结 前言 在上一篇博客中,介绍了一种在Qgis中基于QMetaTiles插件进行xyz瓦…

Linux---环境变量、$符号、自行设置环境变量

1. 环境变量 环境变量是操作系统(Windows、Linux、Mac)在运行的时候,记录的一些关键性信息,用以辅 助系统运行。 在Linux系统中执行:env命令即可查看当前系统中记录的环境变量 环境变量是一种Key-Value型结构&…

chatgpt赋能python:Python如何选取CSV某几列数据

Python如何选取CSV某几列数据 在数据处理过程中,CSV是一种非常常见的数据文件类型。CSV文件中的数据由逗号分隔的值(Comma-Separated Values)组成。处理CSV数据的任务之一是从CSV文件中选择特定的列数据,以进行数据分析或处理。在…

shell脚本基础

目录 一、概述 二、shell (一)shell命令解释环境 (二)类型 (三)查看系统中支持的shell:cat /etc/shells (四)查看系统默认shell: echo $SHELL 三、变量 (一&…

HTMLCSS Day04 CSS盒模型

文章目录 1.盒子组成盒子属性( Box properties)marginborderpaddingwidth & height盒子一般指的是块元素,盒子是我们布局的重要机制。一个盒子应该由外边距、边框、内边距、内容组成。 - width & height- 边框属性1.什么是边框?2.边…

TiDB Contributor 资料汇总

作者: Billmay表妹 原文来源: https://tidb.net/blog/cf95cdb7 开源社区建设 TiDB 社区是由 TiDB 生态中的开发者、用户、合作伙伴一起建立的分享、学习平台。TiDB 线上社区汇聚了 29149 位 TiDB 资深用户(注册用户数)&#x…

将一个一维数组前段和后端的0元素去除的numpy.trim_zeros()方法

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 除去一维数组第一个非零元素之前的零 除去一维数组最后一个非零元素之后的零 numpy.trim_zeros() 选择题 关于以下代码说法错误的一项是? import numpy as np a np.array([0,0,1,0,2,0,0])…

前端Vue分享菜单按钮弹框、微博分享、QQ分享、微信好友、朋友圈

前端Vue分享菜单按钮弹框、微博分享、QQ分享、微信好友、朋友圈 &#xff0c; 下载完整代码请访问uni-app插件市场址:https://ext.dcloud.net.cn/plugin?id13085 效果图如下&#xff1a; #### 使用方法 使用方法 <!-- 分享 ref: 设置一个唯一ref contentHeight&#xff…

记一次fastjson事件应急响应

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 事件背景介绍02 事件分析过程03 事件分析结果04 安全加固建议 01 事件背景介绍 某内部应急演练中&#xff0c;安全部门收到通知&#xff0c;称公司内部资产被入侵&#xff0c;且可能已经开始内网横…

YOLO V2原理总结

yolo v2在yolo v1的基础上添加或更换了一些内容&#xff0c;一定程度上结局了yolo v1的一些问题。 ✨1 概括 做出的改变有8个&#xff1a; 添加Batch Normalization层高分辨率主干网络anchor box机制全卷积网络结构新的主干网络K-means聚类先验框使用更高分辨率特征多尺度训练…

(十)异步-委托异步调用(4)

一、委托异步执行 当委托对象被调用时&#xff0c;它调用其调用列表中包含的方法。这是同步完成的。 如果委托对象在调用列表中只有一个方法&#xff08;引用方法&#xff09;&#xff0c;它就可以异步执行这个方法。委托类有两个方法&#xff0c;叫作 BeginInvoke 和 EndInv…

【计算机网络】进程崩溃或网络中断后,TCP 连接还存在吗?

【计算机网络】进程崩溃或网络中断后&#xff0c;TCP 连接还存在吗&#xff1f; 参考资料&#xff1a; TCP 连接&#xff0c;一端断电和进程崩溃有什么区别&#xff1f; 拔掉网线后&#xff0c; 原本的 TCP 连接还存在吗&#xff1f; TCP/IP卷一:94—TCP保活机制 TCP Keepaliv…

记一次gitlab应急响应

为方便您的阅读&#xff0c;可点击下方蓝色字体&#xff0c;进行跳转↓↓↓ 01 事件背景介绍02 事件分析过程03 事件分析结果04 安全加固建议 01 事件背景介绍 某内部应急演练中&#xff0c;态势感知平台上出现gitlab RCE漏洞攻击成功告警&#xff0c;现需根据流量情况进行安全…