今年早些时候编译并烧录过OpenHarmony系统,从1.0版本到2.0版本变化很大,都有在3516开发板上跑过,虽然说2.0增加了Linux内核,界面更接近手机系统,但是离真正的HarmonyOS还相去甚远,如果想达到手机端HarmonyOS的效果,可能需要结合OpenHarmony框架和AOSP内核,今天就先来尝试自己编译一下AOSP11,为之后可能进行的探索做一些预研。
前期准备
- 硬件设备当然是配置越高越好,虚拟机编译至少需要16G内存+300G硬盘空间,我自己的台式机是加到了24G内存,之前内存只有8G,刚开始就编不过去。
- 软件环境我用的是VMware+Ubuntu 20.04系统的虚拟机,虚拟机的安装这里就不多说了,网上有很多。
配置下载源
因为国外地址可能访问不了或者访问速度慢,我们需要添加国内数据源:
打开源列表
- sudo gedit /etc/apt/sources.list
把清华源复制到源列表,之前的源不要动
- 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
保存之后更新源
- sudo apt-get update
- sudo apt-get upgrade
下载源码
配置好国内的数据源之后,我们就可以开始源代码的下载了,网速要尽量快,因为AOSP的源代码光压缩包就有124G,网速不好下载花的时间就太长了。
这里不推荐大家下载压缩包再解压,因为我们的硬盘容量有限,我这里预留了300G的空间,不足以让一个124G的压缩包完成解压,因此,我选择直接下载源文件。
下载git,配置环境变量
- #安装git,配置自己的git账号
- sudo apt-get install git
- git config --global user.email "xxxx@xx.com"
- git config --global user.name "xxxx"
- #配置PATH环境变量
- mkdir ~/bin
- echo "PATH=~/bin:\$PATH" >> ~/.bashrc
- source ~/.bashrc
安装curl
- sudo apt-get install curl
下载repo
- PATH=~/bin:$PATH
- curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
- chmod a+x ~/bin/repo
下载AOSP源码
- #创建并初始化aosp仓库目录
- mkdir aosp
- cd aosp
- repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-11.0.0_r3 --repo-url=https://gerrit-googlesource.lug.ustc.edu.cn/git-repo
- #同步代码
- repo sync
等待代码下载完之后,我们就可以开始编译了。
编译
安装依赖库,AOSP编译需要依赖很多库,而这些Ubuntu系统可能没有自带,因此我们需要提前安装,避免编译到一半报错浪费时间。
- sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib
- sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386
- sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386
- sudo apt-get install git-core gnupg flex bison gperf build-essential
- sudo apt-get install zip curl zlib1g-dev gcc-multilib g++-multilib
- sudo apt-get install libc6-dev-i386
- sudo apt-get install lib32ncurses5-dev x11proto-core-dev libx11-dev
- sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4
- sudo apt-get install lib32z-dev ccache
- sudo apt-get install libssl-dev
- sudo apt-get install libncurses5
初始化编译环境,执行编译命令
- source build/envsetup.sh
- lunch 31
通过lunch指令设置编译目标,就是生成的镜像要运行在什么样的设备上,我这里是准备在模拟器上跑所以选择31(即aosp_x86_64-eng),模拟器是x86的平台,运行速度会更快。这里也可以用编译目标名称如lunch aosp_x86_64-eng,因为不同版本的编译目标名称序号并不相同。
编译目标的格式: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工具。
选择完编译目标之后会打印出对应平台的编译参数。
- make -j8
通过make指令进行代码编译,该指令通过-j参数来设置参与编译的线程数量,以提高编译速度。需要注意的是,参与编译的线程并不是越多越好,通常是根据你机器cup的核心来确定:core*2,即当前cpu的核心的2倍。我的台式机是i7四核处理器,所以这里可以用8线程编译。
接下来就是漫长的等待,如果没有缺少依赖库,会在几个小时之后看到编译成功的信息,编译时间取决于你机器的性能。
这是我虚拟机编译时候的资源占用情况,CPU应该是够用的,使用率一直在50%左右,而内存消耗达到了20G,可见AOSP编译对内存要求相当高,而当我们编译到90%进度的时候,会生成大量文件,对硬盘读写速率要求也很高,我这里用机械硬盘,读写速率最多在十几M,因此在生成文件时硬盘使用率一直在100%,如果有条件可以用固态硬盘来编译,速度应该会快很多。
六个多小时后,终于编译完成了。
运行模拟器
在编译完成之后,就可以通过以下命令运行Android模拟器了,命令如下:
- source build/envsetup.sh
- lunch(选择刚才你设置的目标版本,比如这里我选择的是31)
- emulator
如果你是在编译完后立刻运行模拟器,由于我们之前已经执行过source及lunch命令了,因此现在你只需要执行命令就可以运行模拟器:
- emulator
这里如果你的虚拟机没有开启虚拟化功能,是不能直接跑模拟器的,会报错,这时,需要关闭虚拟机,配置虚拟化选项。
然后重启虚拟机,进入aosp目录再运行模拟器就可以了,这里直接用emulator会报找不到命令的错误,因为我们重启了虚拟机,需要重新初始化我们刚才编译的环境:
- source build/envsetup.sh
- lunch 31
- emulator
这样,便使用我们自己编译的AOSP镜像启动了Android模拟器,可以看到,这个模拟器的界面和我们平时看到的谷歌原生系统是有区别的,因为谷歌系统自带的很多应用并不是开源的,这里安装的都是AOSP内自带的demo应用,界面也没有谷歌原生系统漂亮。
至此,整个AOSP的编译过程就结束了,总的来说,机器硬件是硬性要求,其他方面,编译命令也非常简单,编译脚本都已经写好了,自动化程度非常高,相比之下鸿蒙系统要自己搭建编译环境就麻烦的多了,而AOSP的编译更类似于鸿蒙的docker编译方式,整套环境比较完善,需要额外安装或配置的不多。AOSP编译完成后,会在out/target/product/generic_x86/目录生成一些img文件,而模拟器启动主要用到了这里面的三个文件system.img,userdata.img和ramdisk.img,Linux Kernel则是使用prebuilds目录下对应平台的kernel文件,这些文件在我们编译openharmony的过程中也接触过,十分类似,当我们需要烧录系统的时候,用到的也是这些文件。