AOSP即是Android的开源项目,包含了Android的所有源码,可通过AOSP编译出Android系统,然后刷写到实际设备中或者运行在模拟器中。对于我们的学习而言,我们也可以下载源码进行阅读,研究其设计逻辑。当然,也有很多的在线源码阅读网站可以阅读Android源码,但如果需要调试的话,还是本地下载比较合适。
编译环境
目前Android官网已经不在支持MacOS上编译源码了,需要使用Linux进行编译。这里使用的是VMWare虚拟机下的Ubuntu 22.04作为编译环境。虚拟机从官网下载,目前最新的虚拟机已经免费,不需要在找破解版了,直接官网下载最新的即可。Ubuntu下载从官网下载即可,这里选的是22.04的版本,也可以选最新的版本。
创建虚拟机的时候,最好将虚拟机的核数设置为和实际cpu一致,以便完全利用cpu编译。同时存储空间需要500g,内存也尽量调整的大一些,加上交换空间最好要有32g。
配置环境
编译源码还需要安装一些软件和库,由于下载速度较慢,所以需要先将下载源切换到国内的源。这里配置的是清华源。配置文件是/etc/apt/sources.list
1 2 3 4
| sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo gedit /etc/apt/sources.list
|
然后将以下内容输入文件中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-updates main restricted universe multiverse
deb https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ jammy-backports main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ jammy-security main restricted universe multiverse
|
然后执行以下命令更新源并下载所需的软件。第三条命令是下载编译源码所必须的软件和库,不过大部分的软件在系统中默认都是已经有了的,只有部分需要下载。参考:官网环境配置
1 2 3 4 5 6 7 8 9 10
| sudo apt update sudo apt upgrade
sudo apt install git gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 libncurses5 ib32ncurses-dev x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig
sudo apt install vim
git config --global user.name pppeng git config --global user.email xxxx@163.com
|
下载repo,这里下载的不是谷歌的repo,而是清华源的,方便国内访问。
1 2 3 4 5 6 7 8 9
| mkdir ~/bin PATH=~/bin:$PATH curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo -o repo > ~/bin/repo chmod a+x ~/bin/repo
sudo gedit ~/.bashrc
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
|
源码下载
源码下载需要梯子,不然无法下载到。这里使用的清华源的AOSP,不需要梯子,并且下载速度也挺快的,具体链接:清华源AOSP。就是可以先下载aosp-latest.tar的初始包压缩包,然后再同步到最新代码,这样操作下来是比较快的,比直接同步所有源码速度快一些。
1 2 3 4 5
| curl -OC - https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar
|
下载完初始包之后切换下分支,然后同步到最新的代码即可。分支可以从官网查询,需要梯子:Build ID查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| tar -xvf aosp-latest.tar
cd AOSP
repo init -u https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest -b android-13.0.0_r44
cd .repo/repo git fetch -all git reset --hard origin/stable git pull
cd ../../
repo sync
|
编译系统
同步完成后进入到aosp目录后,可以看到源码已经存在了。直接输入source build/envsetup.sh配置下编译环境,然后输入lunch选择编译目标。最终会输出一大堆的带编号的目标,如果想在模拟器上查看编译的系统的话,选择输入sdk_phone_x86_64-eng,或者输入对应的编码数字也是可以的(这里不会全部列出来,所以可能输出的列表中没有这个选项)。然后输入m即可进行编译。
编译时不要输入m -j16这种,而是单纯的m,让其根据你的CPU来自动选择并发的任务数。
1 2 3 4
| cd AOSP source build/envsetup.sh lunch sdk_phone_x86_64-eng m
|
根据需要选择lunch的目标,这里一定要选择好,毕竟编译一次需要耗费一个多小时。。。注意每次切换后最好执行下make clean,我就因为没有clean导致了出现莫名其妙的问题,排查老半天了。
虚拟机跑不满cpu
编译时打开window的任务管理器,可以看到CPU的利用率并没有达到100%,当然这也是没问题的,只是会编译的比较慢而已。解决方法是在windows上打开设置-系统-电源-电源模式,然后设置为最佳性能。再重新编译,打开任务管理器可以看到cpu跑到100%了。
编译报错ninja 137
1 2 3 4
| ============================================ 14:18:27 ninja failed with: exit status 137
|
编译时基本上没有别的提示,就一句失败了,然后错误码137。这种137的错误码通常都是内存不足导致的,可以看编译日志进行确认,输入tail out/soong.log
1 2 3
| 14:17:11.518992 build/soong/ui/build/exec.go:64: "ninja" executing "prebuilts/build-tools/linux-x86/bin/nsjail" [-x prebuilts/build-tools/linux-x86/bin/ninja -H android-build --cwd /home/feng/Desktop/aosp -t 0 -e --proc_rw -u nobody -g nogroup --rlimit_as soft --rlimit_core soft --rlimit_cpu soft --rlimit_fsize soft --rlimit_nofile soft -R / -B /tmp -B /home/feng/Desktop/aosp -B /home/feng/Desktop/aosp/out --disable_clone_newcgroup -q -- -d keepdepfile -d keeprsp -d stats --frontend_file out/.ninja_fifo droid -j 18 -f out/combined-aosp_arm.ninja -o usesphonyoutputs=yes -w dupbuild=err -w missingdepfile=err] 14:18:27.593425 build/soong/ui/build/exec.go:74: "ninja" finished with exit code 137 (1m16.073s real, 23.135s user, 42.786s system, 11217MB maxrss) 14:18:27.600733 build/soong/ui/build/exec.go:127: ninja failed with: exit status 137
|
首先需要通过out/soong.log查看具体的报错信息,然后排查是谁发生异常。这里实际也没有任何信息,只显示了退出时ninja的错误码是137。然后查下系统log:cat /var/log/syslog | grep ninja
1
| 14:18:25 ubuntu kernel: [ 6902.917239] Out of memory: Killed process 21126 (ninja) total-vm:5222380kB, anon-rss:3099840kB, file-rss:0kB, shmem-rss:0kB, UID:1000 pgtables:9260kB oom_score_adj:0
|
可以看到相关的结果是Out of memory导致的ninja被杀死,因此可以判定为内存不足导致的。查看虚拟机内存输入free -h,我这边显示的是24g的内存,2g的交换内存,仍然是不够编译的,需要至少32g的内存。可以通过增加交换内存来达到32g。
1 2 3 4 5 6 7 8 9 10 11
| sudo swapoff -a
sudo fallocate -l 12g /swapfile
sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile
free -h
|
运行模拟器
编译成功之后直接输入emulator即可运行模拟器,如果提示没有这个命令的话,说明是环境有问题,或者lunch的选项不对。可以输入以下命令重新进行编译:
1 2 3 4 5 6 7 8 9
| cd AOSP source build/envsetup.sh
lunch sdk_phone_x86_64-eng
m
emulator
|
无法启动虚拟机
1
| ERROR: x86_64 emulation currently requires hardware acceleration!
|
编译成功之后,可以直接运行emulator启动虚拟机,可能会遇到以上的报错信息,解决方案:
- 关闭虚拟机,然后在
虚拟机-设置-处理器的地方,底下有个虚拟化引擎,将第一个虚拟化Intel VT-x/EPT或AMD-V/RVI(V)勾选,然后确定即可 - 按
win键搜索内核隔离,然后将该选项关闭,不然无法打开虚拟机
执行以上两步操作后,再输入emulator即可成功开启虚拟机了。
