1、前言
Android的编译环境作为深入学习Android的基础,不可或缺,能够完整下载Android源代码并编译成功,对深入学习Android是非常关键和重要的一步。Android环境搭建比较繁琐和枯燥,大家需要有足够的耐心,去一步一步的解决问题,否则就很容易会编译失败或者没有办法在Google手机上调试通过。
2、构建编译环境
根据AOSP官网中关于“构建编译环境”中描述,我们可以了解到目前只能使用Linux或者macOS进行源码级的开发。
路径:https://source.android.google.cn/setup/build/initializing
构建编译环境
本部分介绍了如何设置本地工作环境来编译 Android 源代码文件。您必须使用 Linux 或 macOS;目前不支持在 Windows 环境下编译。
2.1、虚拟机选择
如果您有Linux或者Mac操作系统的开发设备,那么部分就可以直接跳过。
如果您常用的开发设备是Windows操作系统的话,那么可以考虑用虚拟机去学习或者研究Android源代码。
目前市面上有两款虚拟机软件,大家自行选择其中一款即可。
2.1.1、下载VirtualBox及其扩展包
在VirtualBox的下载页中下载最新的安装包和扩展包,下载完成后将得到以下两个文件:
- VirtualBox-6.1.8-137981-Win.exe
- Oracle_VM_VirtualBox_Extension_Pack-6.1.8.vbox-extpack
2.1.2、安装VirtualBox
双击可执行文件 “VirtualBox-6.1.8-137981-Win.exe”,
这个部分只需要您做出肯定的回答就可以完成虚拟机的安装。
2.1.3、添加扩展包
按照以下的步骤,完成扩展工具包的添加。
- 启动VirtualBox,然后点击扳手图标按钮“全局设定(P)”
- 在左边的Tab页找到“扩展”选项卡,然后在右侧中部点击“+”图片按钮。
- 在弹出的文件选择对话框里,选择前面获取到的扩展包“Oracle_VM_VirtualBox_Extension_Pack-6.1.8.vbox-extpack”。
- 在"虚拟电脑控制台 - 问题"画面中,点击“安装”按钮。
- 在"Virtual Box 许可" 画面中,将许可证书滑动到最后,点击“我同意(A)”按钮。
- 完成扩展包的安装。
2.2、安装Ubuntu
那我们应该下载什么版本的Ubuntu操作系统呢,根据AOSP官网的提示,64位的Ubuntu LTS (14.04) 风险小一些。
路径:https://source.android.google.cn/setup/build/initializing
设置 Linux 编译环境 以下说明适用于所有分支(包括 master)
我们会定期在 Ubuntu LTS (14.04) 和 Debian 测试版本中对 Android
编译系统进行内部测试。其他大多数分发版本都应该具有所需的编译工具。
如果是 Gingerbread (2.3.x) 及更高版本(包括 master 分支),需要使用 64 位环境。如果是较低的版本,则可以在 32 位系统中编译
笔者对Ubuntu LTS (14.04)、Ubuntu LTS (18.04)以及Ubuntu LTS (20.04)进行了关于系统包安装和源码的编译进行了确认,其中Ubuntu LTS (14.04)和Ubuntu LTS (18.04)没有问题。但是Ubuntu LTS (20.04)会有一些问题,后面会对这方面做出说明。
Ubuntu LTS (18.04)和Ubuntu LTS (20.04)的系统界面比Ubuntu LTS (14.04)要漂亮酷炫。Ubuntu LTS (20.04)系统界面跟Windows操作比较相似,美中不足的地方是界面更新会有卡顿和延迟,期待后面版本的改善。
综上,笔者建议大家使用Ubuntu LTS (18.04)作为源码的编译系统,减少为解决不兼容而浪费的时间,虽然笔者为了尝鲜使用了Ubuntu 20.04 LTS。
2.2.1、下载最新的Ubuntu桌面版(Ubuntu 20.04 LTS)
接下来我们需要下载最新版本的Ubuntu桌面版,建议使用加载工具,直接网页下载速度非常的慢。
路径:https://ubuntu.com/download/desktop
下载完成以后,您将获得以下可执行文件:
- ubuntu-20.04-desktop-amd64.iso
2.2.2、Ubuntu安装过程
(1)创建虚拟机
- 启动VirtualBox,在管理器的右侧的面板上,点击“新建(N)”图片按钮。
- 在“新建虚拟电脑”画面上,填写一下信息:
- 名称:Ubuntu 20.04 LTS(填入名称以后,类型和版本会自动填写,默认即可)
- 文件夹:选择空间足够的磁盘存放
- 类型:Linux
- 版本:Ubuntu(64-bit)
- 内存大小:笔者的笔记本电脑内存为16G,分配一半(8192M)给虚拟机.点击“下一步(N)”按钮。
- 虚拟硬盘:填写极限使用时的虚拟硬盘大小(比如256G),选择“现在创建虚拟硬盘(C)”单选按钮,然后点击“创建”按钮。
- 虚拟硬盘文件类型:选择"VDI(VirtualBox磁盘映像)"单选按钮,点击“下一步(N)”按钮。
- 磁盘分配类型:选择“动态分配(D)”单选钮,点击“下一步(N)”按钮。
- 文件位置和大小:选择虚拟硬盘的保存位置并设置虚拟硬盘大小,然后单击“创建”按钮。
完成虚拟机的创建,选中虚拟机后,单击“设置”按钮,在弹出的虚拟机设置对话框中可以查看并修改虚拟机的各个参数。
(2)安装Ubuntu 系统软件
- 管理器的右侧的面板上,点击“启动(T)”按钮。
- 在弹出的“选择启动盘”对话框中,单击右侧文件夹小图标。
- 选择虚拟光盘文件“ubuntu-20.04-desktop-amd64.iso”,单击“启动”。
- 进入安装界面。 选择“中文简体”,选择“安装Ubuntu”。
- 键盘布局:一般来说来说,我们的键盘布局为英文键盘,选择“English(US) -English(US) ”,选择“继续”。
- 更新和其他软件:选择“最小安装”和“安装Ubuntu时下载更新”(网络状况不好可以不选),选择“继续”。
- 安装类型:选择“清除整个磁盘并安装Ubuntu”,单击“现在安装(I)”按钮,弹出警告框,选择“继续”。
- 您在什么地方:时区选择,用鼠标单击地图中的“中国”,就会选择“上海”,单击“继续”。
- 您是谁?:新建账户信息,比如用户名,密码等信息,单击“继续”。
- 等待安装完成。
(3)安装增强功能
屏幕分辨率较低,需要安装增强功能:
- 点击菜单“设备”
- 点击“安装增强功能”,在弹出的对话框里,点击“运行” 。
- 输入登录系统的密码,点击授权,就开始自动安装。
- 在系统的左侧右击光盘,选择“弹出”光盘。
- 重启Ubuntu系统
- 视图–> 全屏模式,验证屏幕分辨率。
- 完成安装增强功能。
2.3、安装OpenJDK
从Android 5.0 开始,使用OpenJDK编译源码。
Android 版本 | JDK | 备注 |
Android 2.3.x ~ Android 4.4.x | JDK 6 | |
Android 5.x ~ Android 6.x | OPenJDK 7 | |
Android 7.x ~ Android 10.0 | OPenJDK 8 |
根据提示,无需另行安装OpenJDK,那么跳过此步骤。
路径:https://source.android.google.cn/setup/build/requirements
AOSP 中的 Android master 分支带有预编译版本的 OpenJDK;因此无需另行安装。
旧版 Android 需要单独安装 JDK。在 Ubuntu 上,请使用 OpenJDK。
如果想安装可以执行以下命令:
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
2.4、更改镜像源
(1)先执行以下命令:
# 查看系统版本
lsb_release -c
# 备份sources.list并修改文件访问权限
sudo cp -v /etc/apt/sources.list /etc/apt/sources.list.backup
sudo chmod 777 /etc/apt/sources.list
(2)更改镜像源
国内有很多镜像源,比如有清华源和阿里云源等,选择其中一个就可以了。
笔者选择了阿里云源。
- 清华源镜像:https://mirror.tuna.tsinghua.edu.cn/help/ubuntu/
- 阿里云镜像:https://developer.aliyun.com/mirror/ubuntu?spm=a2c6h.13651102.0.0.3e221b11rNHPCb
sudo apt-get install vim
vim /etc/apt/sources.list
# 把下载源替换为国内的镜像源
deb http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ focal-backports main restricted universe multiverse
(3)修改完软件源后,更新软件列表和软件
sudo apt update
sudo apt upgrade
# 更新有失败项的话,执行下面语句以后重复上面两句命令
# sudo apt-get update
# sudo apt update
# sudo apt upgrade
2.5、Ubuntu系统工具包更新升级
安装所需的软件包
路径:https://source.android.google.cn/setup/build/initializing
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev libgl1-mesa-dev libxml2-utils xsltproc unzip
因为网络异常或者其他异常,这次工具包一次不能下载或者更新。
可以重复执行几次,直到控制台提示均已经安装或者更新完毕。
下面是笔者对Ubuntu 14.04 LTS、Ubuntu 18.04 LTS以及Ubuntu 20.04 LTS系统工具包更新的进行了确认,供大家参考。
- Ubuntu 14.04 LTS、Ubuntu 18.04 LTS能够顺利安装和更新。
- Ubuntu 20.04 LTS有三个包被替换了,"lib32ncurses5-dev"会导致编译不通过。
vim /etc/apt/sources.list
# 添加Ubuntu 14.04 LTS的资源列表
deb http://us.archive.ubuntu.com/ubuntu/ xenial main universe
deb-src http://us.archive.ubuntu.com/ubuntu/ xenial main universe
# 另一种工具包安装工具
sudo apt install aptitude
No. | 系统工具包 | 确认 | 执行命令 | 确认结果 | 问题 | 解决方案 |
1 | git-core | -y | sudo apt-get install -y git-core | NG | selecting ‘git’ instead of ‘git-core’ | sudo aptitude install git-core |
2 | gnupg | sudo apt-get install gnupg | OK | - | ||
3 | flex | -y | sudo apt-get install -y flex | OK | - | |
4 | bison | -y | sudo apt-get install -y bison | OK | - | |
5 | gperf | sudo apt-get install gperf | OK | - | ||
6 | build-essential | -y | sudo apt-get install -y build-essential | OK | - | |
7 | zip | sudo apt-get install zip | OK | - | ||
8 | curl | -y | sudo apt-get install -y curl | OK | - | |
9 | zlib1g-dev | sudo apt-get install zlib1g-dev | OK | - | ||
10 | gcc-multilib | -y | sudo apt-get install -y gcc-multilib | OK | - | |
11 | g+±multilib | -y | sudo apt-get install -y g+±multilib | OK | - | |
12 | libc6-dev-i386 | sudo apt-get install libc6-dev-i386 | OK | - | ||
13 | lib32ncurses5-dev | -y | sudo apt-get install -y lib32ncurses5-dev | NG | selecting ‘lib32ncurses-dev’ instead of ‘lib32ncurses5-dev’ | sudo aptitude install lib32ncurses5-dev |
14 | x11proto-core-dev | -y | sudo apt-get install -y x11proto-core-dev | OK | - | |
15 | libx11-dev | -y | sudo apt-get install -y libx11-dev | OK | - | |
16 | lib32z-dev | -y | sudo apt-get install -y lib32z-dev | NG | selecting ‘lib32z1-dev’ instead of ‘lib32z-dev’ | sudo aptitude install lib32z1-dev |
17 | libgl1-mesa-dev | -y | sudo apt-get install -y libgl1-mesa-dev | OK | - | |
18 | libxml2-utils | sudo apt-get install libxml2-utils | OK | - | ||
19 | xsltproc | sudo apt-get install xsltproc | OK | - | ||
20 | unzip | sudo apt-get install unzip | OK |
3、Android 源代码下载及编译过程
3.1 、源代码下载
3.1.1 、安装python
由于repo脚本是Android项目编写的Python脚本,用来统一管理Android项目的代码仓库,
所以首先要确保安装了Python 2.7。
$ python
---
Command 'python' not found, did you mean:
command 'python3' from deb python3
command 'python' from deb python-is-python3
---
$ sudo apt-get install python
$ python
---
Python 2.7.18rc1 (default, Apr 7 2020, 12:05:55)
[GCC 9.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
---
3.1.2 、安装 Repo
Repo 是一款工具,可让您在 Android 环境中更轻松地使用 Git。
- 确保您的主目录中有一个 bin/ 目录,并且它包含在您的路径中:
mkdir ~/bin
vim ~/.bashrc
# 在文件的最后添加下面一行代码,保存退出
PATH=~/bin:$PATH
# 生效修改
source ~/.bashrc
- 下载 Repo 启动器,并确保它可执行:
# curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
curl https://mirrors.tuna.tsinghua.edu.cn/git/git-repo > ~/bin/repo
export REPO_URL='https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'
chmod a+x ~/bin/repo
3.1.3、工作目录设置
创建一个空目录来存放您的工作文件。
为其提供一个您喜欢的任意名称:
mkdir WORKING_DIRECTORY # mkdir -p aosp/Android10
cd WORKING_DIRECTORY # cd aosp/Android10
3.1.4、配置git个人信息
配置git账户信息,用于提交代码到Gerrit上,进行代码审查。
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
// 查看配置的git信息
cat ~/.gitconfig
---
[user]
name = Your Name
email = you@example.com
---
3.1.5、获取源码分支
运行 repo init 以获取最新版本的 Repo 及其最新的问题修复。您必须为清单指定一个网址,该清单用于指定 Android 源代码中包含的各个代码库将位于工作目录中的什么位置。
# repo init -u https://android.googlesource.com/platform/manifest
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest
路径:https://source.android.google.cn/setup/start/build-numbers#source-code-tags-and-builds
Build | 标记 | 版本 | 支持的设备 | 安全补丁程序级别 |
QQ2A.200501.001.B3 | android-10.0.0_r36 | Android10 | Pixel 2、Pixel 2 XL | 2020-05-05 |
6440158 | android-9.0.0_r56 | Pie | 2018-08-05 |
要检出 master 之外的其他分支,请使用 -b 指定此分支。
# repo init -u https://android.googlesource.com/platform/manifest -b android-10.0.0_r36
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-10.0.0_r36
同步源代码:
#repo sync -jx (x:x为线程数,一般是CPU核心的2倍为佳)
# 根据清华镜像网站的提示降低服务器负载的要求,推荐线程数为4比较合适,
# 另外推荐错峰下载,比如晚上下载)
repo sync -j4 --no-tags
# 支持续传
# repo sync
3.1.6、常见问题
(1)虚拟机存储不足
关闭当前虚拟机,回到VirtualBox管理页面。这种调整方案将会导致一直黑屏启动不了。
这种设置只有在虚拟机创建完成后,操作系统还没有安装的情况下调整的。
在设置动态存储空间的时候设置一个足够的虚拟空间是很有必要的,要千万注意。
介质(M)
–> 属性(P)
–> 虚拟机文件选择 --> 属性(P)
–> 拖动滑块,调整大小
(2)使用每月更新的初始化包
笔者下载源码使用了两天三夜,才能下载完代码。
根据清华镜像网站(注:参考文献1)的提示,初次可以使用初始化包,还是非常的贴心,建议大家使用。
wget -c https://mirrors.tuna.tsinghua.edu.cn/aosp-monthly/aosp-latest.tar # 下载初始化包
tar xf aosp-latest.tar
cd AOSP # 解压得到的 AOSP 工程目录
# 这时 ls 的话什么也看不到,因为只有一个隐藏的 .repo 目录
repo sync # 正常同步一遍即可得到完整目录
# 或 repo sync -l 仅checkout代码
(3)gnutls_handshake() 错误解决方案
1)根据stackoverflow的提示:
error: gnutls_handshake() failed” when connecting to https servers
2)将gnutls替换成openssl,重新打包安装。
$ sudo apt-get update
$ sudo apt-get install build-essential fakeroot dpkg-dev
$ sudo apt-get build-dep git
$ mkdir ~/git-openssl
$ cd ~/git-openssl
$ apt-get source git
# Remember to replace 2.25.1 with the actual version of git in your system.
$ sudo dpkg-source -x git_2.25.1-1ubuntu3.dsc
$ cd git-2.25.1
# replace all instances of libcurl4-gnutls-dev with libcurl4-openssl-dev.
$ gedit debian/control
$ sudo apt-get install libcurl4-openssl-dev
$ sudo dpkg-buildpackage -rfakeroot -b
# if it's failing on test, you can remove the line TEST =test from the file debian/rules
$ gedit debian/rules
$ sudo dpkg-buildpackage -rfakeroot -b
# find the log:dpkg-deb: building package 'git' in '../git_2.25.1-1ubuntu3_amd64.deb'.
sudo dpkg -i ../git_2.25.1-1ubuntu3_amd64.deb
3)重启控制台,再次执行同步。
repo sync -j1
当出现以下日志信息以后,代表您的代码终于下载成功了。
笔者认为学习AOSP就是一种修行,请多准备一些您的耐心。
...
Fetching projects: 100% (746/746), done.
Checking out projects: 100% (746/746), done.
repo sync has finished successfully.
3.2 、编译源代码
源代码下载完成以后,就可以开始编译源代码。
- 整体编译:初次编译的时候,需要整体编译。初次编译时间较长,笔者是编译了一下午。
- 模块编译:局部修改的时候,只需要编译当前模块就可以了。
3.2.1、整体编译
make:不带任何参数,用于编译整个系统,编译时间比较长,除非是进行初次编译否则不建议此种做法。
$ cd ~/aosp/Android10
$ source build/envsetup.sh(或者 . build/envsetup.sh)
$ lunch
...
# 笔者的测试设备是Google Pixel所以输入aosp_sailfish-userdebug或者前面的数字
Which would you like? [aosp_arm-eng] (输入编译的产品名字或者输入前面的数字)
$ make update-api -jx
$ make -jx(x为CPU核心的2倍为佳)
3.2.2、模块编译
模块编译分三种:make、mmm、mm
导入编译环境:
cd ~/aosp/Android10
source build/envsetup.sh
- make module name:只知道目标模块的名称,则可以在代码根目录下执行 “make 模块名 ”的方式编译目标模块。
make SystemUI
- mmm module path:该命令编译指定目录下的目标模块,而不编译它所依赖其他模块。
mmm frameworks\base\packages\SystemUI
- mm: 进入对应的应用模块代码所在目录执行mm命令,mm和mmm编译的速度都很快。
cd frameworks\base\packages\SystemUI
mm
以上三个命令都可以用-B选项来重新编译所有目标文件。
虽然从编译速度上mmm,mm都差不多,因为mmm不涉及目录的切换,
所以建议使用 “make 模块名” 的方式分模块编译。
4、参考文献