AOSP-下载并编译源码

Post on Jul 05, 2021 by Wei Lin

搭建环境

搭建构建环境——source.android

Ubuntu 18.04环境:

sudo apt install git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig

注:Ubuntu 20.04应该也可以,不确定是否还需要安装其它库。

安装repo

选择一个文件夹作为源码目录,在该源码根目录下:

mkdir ~/bin					# 准备环境变量目录
PATH=~/bin:$PATH			# 添加到环境变量(仅当前终端有效)
# 将repo下载到环境变量目录下
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo	# 修改执行权限

下载源码

下载源代码——Google

Android 镜像使用帮助——清华大学开源软件镜像站

初始化

最新Android版本:

repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest


如果需要某个特定的 Android 版本(列表),修改-b参数即可,如:

repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-12.1.0_r20
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r15


之后会在当前目录出现一个.repo文件夹:

下载并编译源码1.png

下载源码

# 同步源码树(以后只需执行这条命令来同步):
repo sync

或者:
# 使用8线程下载代码
repo sync -j8

注:下载全部代码确保硬盘有至少200GB容量。

编译源码

导入环境

在源码根目录下,执行以下命令:

source build/envsetup.sh		# 导入命令环境
lunch							# 选择要编译的项目,如aosp_arm64-eng
下载并编译源码2.png


lunch选项解释:

参数 说明
aosp 一个全功能的Android,有时也称为通用系统映像
x86,x64,arm,arm64等 Android系统运行时所在设备的CPU架构
user 正常的发行版Android系统
eng 带有附加调试工具的Android系统
userdebug 具有 root 访问权限和调试功能
redfin,raven等 设备代号,如redfin表示Pixel 5
car 未知,应该指车载系统
cf 未知

make编译

编译命令:

make -j8					# 全编译
make services -j8			# 编译services
make framework -j8		# 编译framework,Android 10(Q)机之前版本用此命令
ninja framework-minus-apex -j8 		# Android 11(R)及之后版本用此命令

注:make -j8全编译13.0.0_r15耗时大约2h40min,根据具体硬件设备有所不同。输出文件夹out约110GB。

ninja编译

在第一次使用make编译之后,之后如果修改过源码,则可以使用ninja编译,相较于make速度较快。


(1) 源码项目第一次使用ninja时

在源码根目录执行以下命令:

source build/envsetup.sh
lunch aosp_arm64-eng			# 选择要编译的项目

croot		# 回到源码根目录
cp prebuilts/build-tools/linux-x86/bin/ninja out/host/linux-x86/bin/
cp prebuilts/build-tools/linux-x86/lib64/* out/host/linux-x86/lib64/

# 建立软链接(注意替换具体机型名)
# 如combined-aosp_arm64.ninja
ln -sf out/combined-<product_name>.ninja build.ninja


(2) 之后每次执行以下快速编译命令

ninja framework -j8 		# 编译framework模块
ninja framework-minus-apex -j8 		# Android 11(R)及之后版本用此命令
ninja services -j8 			# 编译services

常见问题

(1) ninja编译后再用mmm或make编译错误

下载并编译源码3.png


解决:删除out/host/linux-x86/lib64/文件夹。

运行模拟器

说明

(1) lunch命令

需要注意的是,如果是要在x86或x64平台上运行编译好的镜像,那么lunch的参数则应该选择带有x86_64后缀的,如lunch sdk_pc_x86_64-userdebug和sdk_phone_x86_64等。如果编译的是其它平台的镜像,则执行emulator无法在电脑上运行,会报出错误。

Google官网给出的示例是lunch aosp_arm-eng,但在实际编译完成后执行emulator是无法正常运行的。


(2) 可以在x86及x64运行的项目

以下项目在lunch选择菜单中没有,但实际上可以执行。

sdk_x86_64-userdebug

sdk_phone_x86_64-userdebug

sdk_pc_x86_64-userdebug

注:sdk_x86_64-eng和sdk_phone_x86_64的编译结果目录都是out/target/product/emulator_x86_64


(3) 加载环境

若关闭了终端,则运行模拟器需要重新执行以下命令。

source build/envsetup.sh
lunch xxx
emulator

模拟器运行

注:使用模拟器需要在电脑BIOS中开启虚拟化支持。

使用make全编译后,执行emulator命令即可打开模拟器,会自动加载编译好的镜像文件。但如果lunch命令选择了用于其它设备的安卓系统,则会出现错误,常用lunch命令及模拟器运行如下。


(1) lunch aosp_arm64-eng

全编译后执行”emulator”打开模拟器失败且提示:

qemu-system-aarch64: Could not open '/xxx/android-13.0.0_r30/out/target/product/generic_arm64/userdata-qemu.img': No such file or directory

原因:生成的是专用于arm平台的安卓系统,而电脑通常都是x86或x64平台的,所以无法运行。


(2) lunch aosp_x86_64-eng

全编译源码后打开模拟器,也出现了类似提示:

qemu-system-x86_64: Could not open '/xxx/android-13.0.0_r30/out/target/product/generic_x86_64/userdata-qemu.img': No such file or directory

原因:暂时未知。


(3) lunch sdk_phone_x86_64-userdebug

成功打开模拟器

下载并编译源码4.png


(4) lunch sdk_pc_x86_64-userdebug

成功打开模拟器

下载并编译源码5.png

其它

ROM与源码匹配

ROM列表:https://developers.google.com/android/images

源码列表:https://source.android.com/docs/setup/about/build-numbers#source-code-tags-and-builds


源码列表示例:

image-20230726000131708


ROM列表示例:

image-20230726000214435

根据Build ID匹配到刷机包和源码。

为什么要使用ninja?

测通常使用make编译会有两个阶段:

(1) 先分析Android.bp,将所有需要参与编译的文件的路径都记录下,writing build rules并打包到out/soong/combined-xxx.ninja中,这一步普遍耗时15-20min。

(2) 然后ninja工具通过第一步生成的文件,编译需要编译的模块。(不同模块速度不同,比如services模块只需要大约20s)

优点:直接使用ninja就可以省去第一部分耗时,尤其在反复编译时调试效率提高。


注意:进行ninja之前必须要先make一次(当然要想make必须先根目录source 和 lunch一次),以生成路径文件;如果你的修改增删了模块中文件的名字路径,就必须重新make生成路径文件。