其实我现在的工作已经跟Android源码八竿子打不到一块了,开发应用虽然也会有一些有难度的地方,但需要看Android源码的时候几乎不存在。但最近遇到了一件事情,有朋友跟我说,你之前不是做过Framework的开发吗,我这里有个项目你看能不能做……尴尬的发现我现在不仅仅做不了这工作,甚至已经缺乏理清思路的能力,因为对这块太过于生疏了。这可不行,果断要重新拿起来。
一、编译的软硬件环境需求
由于大家现在应该不会编译特别老的Android源码了(指的是2.2或更老的),64位系统现在是必然的选择。我还是依照自己的习惯选择Ubuntu系统。Long long ago,在上一家公司做开发的时候用的还是Ubuntu10.04和12.04,后来我自己玩用的是14.04,现在都快2018年了,虽然18.04这个版本还没出,但怎么着也得用个16.04是吧。别问我为啥老用LTS版本,因为Google官方的文档推荐的就是这些系统,可能是因为Canonical对LTS系统支持周期长吧。
硬件方面,对硬盘的需求比较大,如果你是用Repo的方式更新源码,源码下载完并把一些压缩的包解压后,整个源码目录就有60G-70G的大小,再通过编译生成一些镜像和库文件,占用的空间就更大了。120GB是最低需求了,如果可能的话就给更多一些,比如有人还会在这个环境下进行App的开发。内存和CPU自然是越强越好了,内存+swap最好超过16G。
值得一提的是,硬盘如果是SSD固态硬盘,可以极其显著的提升编译速度,我编译的时候查看硬件资源,发现硬盘的使用率一直在95%-100%居高不下。我这里的硬件是在虚拟机里面装的Ubuntu16.04.3,CPU是E3 1231V3,给虚拟机4个线程,内存给了8GB,硬盘直接划了200G。
- 安装JDK
Java在Android中的角色不需多言,没JDK肯定是不行的。但是众所周知,Oracle与Google在Java领域的撕逼非常激烈甚至是惨烈,直接用OracleJDK的话Oracle养着的大批法务人员很快就会找上门来,虽然Google也不是吃素的但总要耗费大量心思,它无时无刻不在想着摆脱Oracle的纠缠(在App开发层面让Kotlin上位就是一个非常明显的标志),所以最近几个Android大版本(我印象中好像是从5.0还是从5.1开始)源码编译一律使用OpenJDK(实际上用OracleJDK也能编译,但需要有一些改动)。
因为用的是Ubuntu16.04,所以安装OpenJDK只需要2行命令:
sudo apt-get update sudo apt-get install openjdk-8-jdk
- 系统安装所需要的package
官方文档给出的需要安装的包,有这些:
sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-mul tilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip
如果一切顺利,那么从理论上说,你已经完成了Android源码编译环境的搭建。当然在安装以上package的时候,有可能会遇到各种各样的问题。
这一步,可以参考官方文档:https://source.android.com/setup/initializing
二、下载Android源码
这一步可以参考官方文档:https://source.android.com/setup/downloading
首先安装Repo,Repo是Google为我们提供的,专门用来处理Android相关的git操作的。我们知道Android源码体积十分巨大(有几十GB),而且实际上是由无数个小的git工程组成的,如果单纯操作git命令,怕是要搞到天荒地老,而使用了Repo后几个简单的命令就直接把整个AOSP的源码搞定了。
首先来到自己的home目录,比如我在我的系统是cd到了/home/kael这里。
然后执行2步操作:
mkdir ~/bin PATH=~/bin:$PATH
之后是下载Repo工具,并授予执行权限
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repochmod a+x ~/bin/repo
下载完成后,就可以初始化Repo了,你可以理解为,这一步是为了让Repo工具知道你要下载的是哪个分支的Android源码,本质上就像是给git设置了代码源一样。
先创建一个目录,这个目录就是待会用来下载源码的,名字任意,比如叫AndroidSource:
mkdir WORKING_DIRECTORY cd WORKING_DIRECTORY
然后给git配置一下名字和邮箱,虽然我完全get不到Google为什么要让我们这么做:
git config --global user.name "Your Name" git config --global user.email "you@example.com"
接下来,就是选择你要下载的Android源码分支了,如果选择master分支,那么只需要
repo init -u https://android.googlesource.com/platform/manifest
就可以了,这样下载下来的就是最新的主分支代码。而如果你是有目的有针对性的下载源码,那么可以参考https://source.android.com/setup/build-numbers#source-code-tags-and-builds来选择你需要的分支。
举例来说,如果你手头有Nexus 5X手机,那么你可以选择android-8.0.0_r32,这样你编译出来的system镜像是可以自己刷到手机上的(有风险,谨慎行事)。
repo init -u https://android.googlesource.com/a/platform/manifest -b android-8.0.0_r32
完成了Repo的初始化后,执行sync就可以了。
repo sync
OK,如果一切正常,执行之后你就能看到源码正在哗哗的下载。然而,由于众所周知的原因,下载Android源码很有可能遇到网络方面的问题,嗯,这个嘛,作为开发人员应该都有自己的解决方案吧……不多说,说多了搞不好俺的博客都没得玩了。
等到天荒地老了,下载完了,就可以开始编译啦。
三、编译源码
现在源码的clean命令跟很久以前不一样了,我记得以前是clean的。运行
make clobber
可以清掉之前编译结果。当然刚下载源码的不需要运行这一步。
然后是初始化编译环境:
source build/envsetup.sh
如果懒得打字,可以用“.”代替source,也就是
. build/envsetup.sh
然后选择编译的目标模式,有3种可选,分别是
user | 用户模式,限制最多,如果你编译的结果要作为上市产品,那么就用这种模式,此模式就像是是正常的手机ROM那样,没有root权限,默认关闭了各种打印log。 |
userdebug | 提供了root权限,也可以进行debug,适合内测。 |
eng | 基本上开放了全部权限,而且还带了一些额外的debug工具,开发阶段当然选择此模式了。 |
鉴于大家基本都是自己研究,所以肯定选择eng模式了。
lunch aosp_arm-eng
然后就是真正的编译了
make -j4
这里的-j4参数,就是在设定编译线程数量,根据编译环境的硬件配置来决定。如果你的电脑是多路CPU,一大堆核心甚至还有超线程,那么数量就可以调大一些,比如make -j32。如果你的电脑很一般,那么线程数调整为4、2甚至是1我都见过,垃圾电脑如果开启太多线程,结果很可能是根本编译不完,直接死机。
然后就是默默的等待编译的完成啦,一般来说编译时间超过1个小时是很正常的,如果配置太差,几个小时也有可能,哈哈还记得当年在公司的时候,用一台赛扬E2140+2G的电脑编译Android 4.0的源码,貌似都得5个小时。我配置为E3 1231V3+16G内存,Ubuntu系统安装在虚拟机里面,虚拟机分配了4个CPU线程与8GB内存,编译时间为2小时10分钟。
编译完成后,整个AndroidSource目录占据了114G的空间,所以多分配点硬盘还是很有必要滴!
2018年2月8日 下午8:02 1F
按照您的分享配置的环境,然后进行了编译,果断OK
感谢,比起网上其他的那些垃圾教程好太多了,突然很后悔一直没装上我的越墙环境
2018年4月7日 下午8:48 B1
@ yougar 其实不越墙也行,国内有不少的镜像源了,比如清华、中科大都有,速度很快的。