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

背景

有时我们需要使用同一套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目录下生成二次开发包。
【干货】Android系统定制基础篇:第四部分-Android二次构建_第1张图片二次开发包
命名
二次开发包的命名规则为

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(芯片平台)

【干货】Android系统定制基础篇:第四部分-Android二次构建_第2张图片产品配置
典型的产品配置目录结构如下:

├─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 -

在这里插入图片描述构建后生成产品固件。
【干货】Android系统定制基础篇:第四部分-Android二次构建_第3张图片

你可能感兴趣的:(Android,android)