硬件设备当然是配置越高越好,虚拟机编译至少需要16G内存+300G硬盘空间
配置环境
-
Ubuntu 最好,安装方式网上一大堆,自行搜索,本文是基于 Ubuntu 22.04.3 LTS
-
更新&&配置
sudo apt-get update sudo apt-get upgrade sudo apt-get -u dist-upgrade sudo dpkg --configure -a sudo apt-get -f install
-
配置 git
sudo apt-get install git -y git config --global user.name "your name" git config --global user.email "your mail"
-
安装 Python
python --version # 如果有则不需要安装 sudo apt-get install python # python 找不到,需要执行 sudo ln -s /usr/bin/python3 /usr/bin/python
-
执行如下命令安装jdk8
sudo apt-get install openjdk-8-jdk -y
-
执行如下命令安装依赖项。
AOSP编译依赖很多库,而这些Ubuntu系统可能没有自带,我们需要提前安装,避免编译一半报错浪费时间。sudo apt-get install git git-core gnupg flex bison gperf zip unzip curl m4 ccache build-essential gcc-multilib g++-multilib tofrodos python-markdown xsltproc zlib1g-dev zlib1g-dev:i386 x11proto-core-dev libc6-dev-i386 lib32ncurses5-dev libx11-dev lib32z-dev libxml2-utils libnss-sss:i386 libssl-dev libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev libncurses5 libncurses5-dev:i386 -y
-
Ubuntu默认不允许普通用户使用USB,所以还应该配置Android USB设备能够被当前用户访问到,则需要执行如下命令
注意:执行该命令需要翻墙
wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules
国内用户可执行如下命令
wget -S -O - http://yunpstatic.oss-cn-beijing.aliyuncs.com/res/android/source/51-android.txt | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules
-
装个看CPU、内存、缓存的htop
sudo apt install htop -y
配置清华镜像
因为国外地址可能访问不了或者访问速度慢,我们需要添加国内数据源:
-
打开源列表
sudo gedit /etc/apt/sources.list1
-
把清华源复制到源列表,之前的源不要动
# tsinghua start deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-updates main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-backports main restricted universe multiverse deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse deb-src https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ focal-security main restricted universe multiverse # tsinghua end
-
保存之后更新源
sudo apt-get update sudo apt-get upgrade
下载源码
在线下载
-
安装repo工具
mkdir ~/bin PATH=~/bin:$PATH curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo #清华 repo # curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo chmod a+x ~/bin/repo
-
下载AOSP源码
#创建并初始化aosp仓库目录 mkdir aosp cd aosp # -b android-13.0.0_r43 选择分支 repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-13.0.0_r43 --repo-url=https://gerrit-googlesource.lug.ustc.edu.cn/git-repo # 下载失败执行 # repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-13.0.0_r43 #同步代码 repo sync #如果你的机器足够好,可以指定更多的任务,如下命令演示使用8个任务同步代码 repo sync -j8
#推荐:后台去同步,ssh断开也没事。 nohup repo sync -j8 >&sync.log & #如果 nohup 运行出错,可尝试如下方式 #后台运行(关闭终端会停止) $repo sync -j8 >&sync.log & [1] 2074542 # 找到后台的 job $ jobs [1]- Running repo sync -j8 >&sync.log & # 当退出会话时,并不会终止被移除的 job $ disown %1
# Tips:下载过程可能出现某些project找不到,可能是镜像问题,也可能是网的问题, # 试试可以单独同步该项目,支持-jN参数,-j4如: repo sync -j4 -c platform/frameworks/layoutlib
预下载包的方式
-
在windows或者Linux上面通过迅雷下载 aosp-latest.tar
#下载初始化包 wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar
-
解压预下载包
# cd AOSP->解压得到的 AOSP 工程目录,这时 ls 的话什么也看不到,因为只有一个隐藏的 .repo 目录 tar xf aosp-latest.tar
-
查看分支信息
cd .repo/manifests git branch -a
-
同步代码
repo init -b android-13.0.0_r43 repo sync # 正常同步一遍即可得到完整目录
下载驱动
-
根据机型查看可刷对应 android 版本的分支和 Build 号
https://source.android.com/docs/setup/about/build-numbers?hl=zh-cn#source-code-tags-and-builds -
根据 build 号选择对应设备的驱动
https://developers.google.com/android/drivers?hl=zh-cn -
将驱动文件下载并解压
# 下载 pixel 6 驱动 wget https://dl.google.com/dl/android/aosp/google_devices-oriole-tq2a.230505.002-9d23e4ab.tgz #解压 tar xf google_devices-oriole-tq2a.230505.002-9d23e4ab.tgz # 解压后得到 extract-google_devices-oriole.sh 脚本 # 切换到 android 源码 根目录 执行脚本,会将对应驱动 copy 到相应的 vendor 目录 ./extract-google_devices-oriole.sh
下载内核
aosp 不包含内核代码,有需要可以单独下载,版本有很多,如:
# common → 通用linux内核、goldfish → Android模拟器内核、msm → 高通MSM芯片
mkdir kernel
cd kernel
git clone https://android.googlesource.com/kernel/goldfish
# 清华镜像
# git clone https://aosp.tuna.tsinghua.edu.cn/kernel/goldfish.git
cd goldfish
# 可以查看有哪些内核版本分支可以下载
git branch -a
# 下载对应版本内核代码
git checkout remotes/origin/android-goldfish-3.18
注:如需编译内核自行搜索
编译 AOSP
初始化编译环境,源码整编
编译目标的格式:BUILD-BUILDTYPE,比如上面的aosp_x86_64-eng的BUILD是aosp_x86_64,BUILDTYPE是eng。
BUILD指的是特定功能的组合的特定名称,即表示编译出的镜像可以运行在什么环境。
其中,aosp(Android Open Source Project)代表Android开源项目;arm表示系统是运行在arm架构的处理器上,arm64则是指64位arm架构处理器,x86则表示x86架构的处理器。
BUILD TYPE则指的是编译类型,通常有三种:
-user:代表这是编译出的系统镜像是可以用来正式发布到市场的版本,其权限是被限制的(如,没有root权限,不能dedug等)
-userdebug:在user版本的基础上开放了root权限和debug权限。
-eng:代表engineer,也就是所谓的开发工程师的版本,拥有最大的权限(root等),此外还附带了许多debug工具。
source build/envsetup.sh
# ② 删除out与中间文件,clean会删除本次设置生成的、clobber会删除所有配置生成的
make clobber
# 运行 lunch 后选择目标产物
# 也可以直接指定编译目标,如:lunch aosp_oriole-userdebug
# 还可以直接用序号,如:lunch 8,但不建议,因为不同的系统版本序号对应可能有偏差~
# ③ 选择编译目标,下述命令会进入菜单,选择相应的版本,输入序号回车
# 编译目标都采用 BUILD-BUILDTYPE 形式,BUILD 表示特定功能代号,BUILDTYPE是以下类型之一:
# user → 权限受限、适用于生产环境,没root权限,不能debug,adb默认处于停用状态;
# userdebug → 与user类似,但具备root权限和debug权限,一般用于调试真机。
# eng → 具有额外调试工具的开发配置,拥有最大的权限(root等),一般用于模拟器。
# 编译目标示例 → Pixel 3a XL的编译目标 → aosp_bonito-userdebug
lunch aosp_x86_64-eng
# ③ 开始编译,后面的-jN参数用来设置编译的并行任务数,CPU核心数为6,N值最好选6-12间
# 根据自己CPU核心数动态修改
make -j6
# 也可以把输出结果打印到log文件中:
make -j6 2>&1 | tee make_build.log
# 编译成功后会生成out目录,比如这里的:~/aosp/out/target/product/bonito
#推荐这个命令,后台运行。
# 参考 https://blog.csdn.net/qq_33215865/article/details/88075462
nohup make -j6 >& make_build.log &
#如果 nohup 运行出错,可尝试如下方式
#后台运行(关闭终端会停止)
$make >& make.log &
[2] 2074542
# 找到后台的 job
$ jobs
[2]- Running make &> make.log &
# 当退出会话时,并不会终止被移除的 job
$ disown %2
源码单编
整编一般会耗费几小时,有时可能只是修改了其中某个应用模块,只需单独编译这个模块,以设置模块为例:
source build/envsetup.sh
lunch aosp_x86_64-eng
# 进入模块目录
cd package/apps/Setting
# 编译单独模块的可选指令如下:
# mm → 编译当前目录下的模块,不编译依赖模块
# mmm → 编译指定目录下的模块,不编译依赖模块
# mma → 编译当前目录下的模块及其依赖项
# mmmma → 编译指定路径下所有模块,切包含依赖
mm
# 编译成功会提示生成文件的存放路径,除了生成Setting.odex外,还会在
# priv-app/Settings目录下生成Settings.apk,可直接 adb push 或 adb install
# 安装APK验证效果,也可以使用 make snod 命令重新打包生成 system.img,运行模拟器查看
编译 AVD (Android 虚拟机镜像)
需要先全量编译一次,直接编译 make emu_img_zip 最后会报 data 目录找不到错误
# 全量编译
source build/envsetup.sh
lunch sdk_pc_x86_64-userdebug
make clobber
make >& make-sdk_pc_x86_64-userdebug.log &
# 加上 emu_img_zip 再次增量编译(很快)
source build/envsetup.sh
lunch sdk_pc_x86_64-userdebug
make emu_img_zip >& emu_img_zip.log &
编译产物镜像打包
真机镜像打包
真机(piexl6)需要的镜像文件如下:
android-info.txt pvmfw.img system_other.img vendor.img
boot.img super_empty.img vbmeta.img vendor_boot.img
dtbo.img system.img vbmeta_system.img vendor_dlkm.img
product.img system_ext.img vbmeta_vendor.img(可能没有)
zip pixel6-img.zip android-info.txt pvmfw.img system_other.img vendor.img boot.img super_empty.img vbmeta.img vendor_boot.img dtbo.img system.img vbmeta_system.img vendor_dlkm.img product.img system_ext.img vbmeta_vendor.img
AVD 镜像打包
编译完会在生成 out\target\product\emulator64_x86_64\sdk-repo-linux-system-images-eng.zip
直接复制解压,替换 AVD 原有镜像
- 替换android-sdk\system-images\android-33\google_apis 下的整个 x86_64
- 替换后先 wipe data
- 然后在 cold boot now
增量编译完也可以复制相应的镜像进行替换
-
avd-镜像全 copy
tar czvf avd-img.tar.gz ./data/* advancedFeatures.ini system/build.prop encryptionkey.img kernel-ranchu ramdisk.img system.img system-qemu.img userdata.img vendor.img vendor-qemu.img VerifiedBootParams.textproto >& tar-avd.log
-
AVD 需要替换的镜像:
system-qemu.img(替换 system.img), vender-qemu.img(替换 vender.img)
ramdisk.img,kernel-ranchu,system/build.proptar czvf avd-img.tar.gz system-qemu.img vender-qemu.img ramdisk.img kernel-ranchu system/build.prop
-
进入AVD manger,刚才创建或者替换好的 AVD,先 Wipe Data 一下,然后 Cold Boot。
repo 切换分支
cd .repo/manifests
# 查看当前分支
repo info
# 切换分支
repo init -b android-13.0.0_r43
# 同步代码
repo sync
# 可已选择后台执行
$repo sync >& sync_13_r43.log &
$jobs
[1]+ Running repo sync &> sync_13_r43.log &
$disown %1
Pixel 6 编译配置
Android 版本:android-13.0.0_r43
Pixel 6 对应驱动级镜像
BuildID:TQ2A.230505.002
Pixel 6 驱动:https://dl.google.com/dl/android/aosp/google_devices-oriole-tq2a.230505.002-9d23e4ab.tgz
原厂镜像:https://dl.google.com/dl/android/aosp/oriole-tq2a.230505.002-factory-6294af63.zip
source build/envsetup.sh
lunch aosp_oriole-userdebug
make clobber
make >& make-aosp_oriole-userdebug.log &
编译产物打包后,替换原厂镜像 image-oriole-tq2a.230505.002 中的相关文件,然后刷机即可
# 在镜像目录文件夹中
# 进入 bootloader 模式
adb reboot bootloader
# 如果没有 unlock 的话,先解锁
fastboot flashing unlock
# 执行刷机 或者 flash-all.sh
flash-all.bat
参考文献
- Android模拟器中替换库和img
- 回滚机制降级
- 安装原始设备制造商 (OEM) USB 驱动程序
- Nexus 和 Pixel 设备的出厂映像 和刷机方法
- 详细的android目录说明
- 镜像文件说明