Android源码、内核编译

Android源码和内核的编译就是一场马拉松,每一个节点都耗时漫长,下载源码、编译源码、下载内核、编译内核,下载中途会断掉,编译中间会失败,求解再重来,又是一轮马拉松,于是每一步都要做好备份和记录,可是30G的源码(编译后已经达到70G)备份一次都需要好久。好在春节伊始我放弃了其他的学习,全力搞这个过程,终于算是拿下了。不过,漫漫长路,这只是一个开头。

我编译的是Android最新稳定版本android-6.0.1_r11,内核是android-goldfish-3.4,平台是Mac OS 10.11。

  • 一、Android源码下载和编译

source.android.com官网对Mac OSX下的编译说的挺详细的了,不过因为你懂的原因,去到官网很不方便,我还是把自己的心路历程记录下来,以便以后再做的时候查找方便。

  • 1、前期准备

这是为后面下载和编译做好环境设置和工具的准备。

  • (1)创建大小写敏感的磁盘镜像文件

Launchpad - 其它 - 磁盘工具,点击菜单 文件 - 新建映像 - 空白映像

如下,在格式中必须选择“OS X 扩展(区分大小写,日志式)”,我在映像格式中选择了“稀疏磁盘映像”,以便未来比较容易地扩展:

不过我发现mac的磁盘工具貌似有bug:点击存储之后,实际生成的磁盘映像文件还是“OS X 扩展(日志式)”的,而不是大小写区分,需要点击该分区文件 - 分区,此时你会发现在“格式”中选择的是“OS X 扩展(日志式)”,把它改为“OS X 扩展(区分大小写,日志式)”,再点应用。

  • (2)确认JDK、XCode版本、make版本

在命令行下输入java -version,确认已经是最新的Java 8了:

输入make -v,确认是3.8.1,据说最新的3.8.2有bug,如果装的是3.8.2,需要退到3.8.1:

我的XCode版本是7.2.1

  • (3)安装所需要的packages

到http://www.macports.org/install.php下载和安装macports,再利用macports下载几个packages:

$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
  • (4)调高文件描述符的限制

编辑~/.bash_profile文件,加入如下内容,把单个进程可打开的文件描述符上限改为1024:

# set the number of open files to be 1024
ulimit -S -n 1024

然后执行source ~/.bash_profile

  • 2、优化编译环境

编辑~/.bashrc文件,添加如下内容,有助于加速编译过程:

export USE_CCACHE=1

然后执行source ~/.bashrc

  • 3、安装repo

编辑 ~/.bash_profile文件,添加:

export PATH=~/bin:$PATH

然后执行source ~/.bash_profile。

下载repo工具,并设为可执行:

$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
  • 4、初始化repo

挂载1-(1)中创建的大小写敏感磁盘映像文件,并在里面创建目录android-6.0.1_r11,假设它的全目录名为WORKING_DIRECTORY,

执行如下命令初始化repo客户端:

cd WORKING_DIRECTORY
repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r11

我把源指向的清华的镜像服务器,它将下载分支android-6.0.1_r11,点击此处查看Android分支的名称列表

如果要下载最新主干代码,则执行:

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest
  • 5、下载Android代码树

注意,接下来我们将进入长夜漫漫的下载过程,执行:

repo sync

我下过几次,每次都要花上四五个小时,而且常常中途会断掉,建议晚上睡觉前走起,运气好的话,第二天早上搞定。如果失败了,还是执行这个命令,会接着上文继续下载。

  • 6、编译Android源码

Android源码的编译步骤仅如下三步:

  • (1)设置环境变量

$ source build/envsetup.sh
  • (2)选择编译目标

$ lunch aosp_arm-eng

官网说这个参数将为模拟器打开所有的调试开关。不带参数直接调用lunch会列出所有的目标选项,但是我没找到每个选项的具体描述。

  • (3)编译

$ make -j4

又是一个漫漫长夜的过程,我的编译大概花了三四个小时,但我没有使用-j4参数,打开这个参数将开启多线程编译。后来缀上这个参数再重新编译,果然效果明显,只用了2个小时12分钟,建议打开。

  • (4)编译问题

build/core/combo/mac_version.mk:38: *****************************************************
build/core/combo/mac_version.mk:39: * Can not find SDK 10.9 at /Developer/SDKs/MacOSX10.9.sdk
build/core/combo/mac_version.mk:40: *****************************************************
build/core/combo/mac_version.mk:41: *** Stop..  Stop.

原因是本机的XCode SDK已经升级到10.11,打开目录:

/Applications/XCode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs,

检查其下的MacOSXxx.xx.sdk即可确认本机的SDK版本,然后修改WORKING_DIRECTORY/build/core/combo/mac_version.mk,将

mac_sdk_versions_supported :=  10.6 10.7 10.8

改为

mac_sdk_versions_supported :=  10.9 10.10 10.11

然后重新启动lunch aosp_arm-eng即可。

 

fatal error: linux/netfilter/xt_DSCP.h: No such file or directory

我在WORKING_DIRECTORY/external/iptables/extensions/../include/linux/netfilter下面能找到该文件,只不过是xt_dscp.h,我把它改名为xt_DSCP.h即可。我不知道为什么会出这样的问题,我的文件系统已经是大小写敏感的了,而且我是直接repo到该文件系统的,如果真的有错误,应该是可重现的。

  • 7、运行emulator

经过两个多小时的编译,终于看到如下结果:

 

在命令行下直接运行

$emulator

即可启动模拟器。启动过程很慢,需要耐心等待:

编译过程做好了各种环境变量的设置:

内核使用的是WORKING_DIRECTORY/prebuilts/qemu-kernel/arm64/kernel-qemu

sysdir默认是WORKING_DIRECTORY/out/target/product/generic/

系统镜像文件分别是sysdir下的system.img、ramdisk.img和userdata.img

 

赶紧把磁盘卸载掉,备份磁盘映像文件!未来就可以在它的基础上做更多尝试,万一踩到屎了,还可以拿这个备份直接来用,不需要再编译一次了。