YeGuli
发布于 2018-02-05 / 4 阅读
0

Android系统源码下载与编译

硬件环境要求

1. 编译环境

按照官方的说法,编译Android 2.3.x及以上版本的系统源码需要64位的系统运行环境来支持,而编译2.3.x以下的版本则需要32位的系统运行环境。

2. 硬盘空间

官方建议最好预留100G的磁盘空间来下载源码,150G的磁盘空间用来编译源码,如果使用了ccache(一个高速编译缓存工具,可以大幅加快gcc的编译速度),那么则需要更大的空间来支持。

3. 内存空间

如果你是在虚拟机上跑linux,官方建议至少需要16G的内存空间,我用来测试的机器只有10G左右的内存空间跑虚拟机,目前跑起来也没太大问题,就是编译源码的过程比较漫长,不知道是否跟内存大小有关。


软件环境要求

1. 操作系统

Android系统的源码的编译支持Linux跟Mac OS两种操作系统,一般情况下,Android系统源码都是在Ubuntu系统上进行开发与测试的,所以如果你准备使用Linux系统来进行源码编译,那一般推荐安装Ubuntu版本的Linux。

下面列出了各Android版本与编译系统版本的对应关系

Linux :

Android版本GNU/Linux
Android 6.0 (Marshmallow) - Android最新版本Ubuntu 14.04 (Trusty)
Android 2.3.x (Gingerbread) - Android 5.x (Lollipop)Ubuntu 12.04 (Precise)
Android 1.5 (Cupcake) - Android 2.2.x (Froyo)Ubuntu 10.04 (Lucid)

Mac OS

Android版本Mac OS (Intel/x86)
Android 6.0 (Marshmallow) - Android最新版本Mac OS v10.10 (Yosemite) or later with Xcode 4.5.2 and Command Line Tools
Android 5.x (Lollipop)Mac OS v10.8 (Mountain Lion) with Xcode 4.5.2 and Command Line Tools
Android 4.1.x-4.3.x (Jelly Bean) - Android 4.4.x (KitKat)Mac OS v10.6 (Snow Leopard) or Mac OS X v10.7 (Lion) and Xcode 4.2 (Apple's Developer Tools)

2.JDK 版本要求

不同的Android版本编译也需要对应的JDK环境,这里列出了各版本之间的对应关系

Android版本JDK版本(Ubuntu)JDK版本(Mac OS)
Android目前最新版本OpenJDK 8jdk 8u45 or newer
Android 5.x (Lollipop) - Android 6.0 (Marshmallow)OpenJDK 7jdk-7u71-macosx-x64.dmg
Android 2.3.x (Gingerbread) - Android 4.4.x (KitKat)Java JDK 6Java JDK 6
Android 1.5 (Cupcake) - Android 2.2.x (Froyo)Java JDK 5

搭建编译环境

根据上面列出的软硬件要求,我们可以根据自己要编译的Android版本以及自己的设备来选择合适的系统及JDK,接下来我们就来说说如何搭建编译环境。

这里我们主要针对Android 8.0的需要的编译环境对Linux进行配置:

设置Linux系统编译环境

1.安装JDK

Android 8.0目前需要openJDK 8的JDK环境

Ubuntu 15.04+

如果你的系统是Ubuntu 15.04及以上版本的话,直接运行如下指令即可直接安装:

$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk
Ubuntu 14.04

如果你使用的是Ubuntu 14.04版本,现在并没有专门针对14.0.4可用的open jdk8的包,但是Ubuntu 15.04 OpenJDK 8的包可以在14.0.4上成功地运行,所以我们下载Ubuntu 15.04 OpenJDK8的安装包来手动安装:

  1. archive.ubuntu.com上依次下载下面列出的64位的open JDK 8 的.deb安装包

openjdk-8-jre-headless_8u45-b14-1_amd64.deb
openjdk-8-jre_8u45-b14-1_amd64.deb
openjdk-8-jdk_8u45-b14-1_amd64.deb

  1. 安装.deb包:
    先运行apt-get指令更新软件列表
$ sudo apt-get update
  1. 接着依次对上面下载的三个deb文件运行如下指令进行安装:
$ sudo dpkg -i 下载的文件地址
  1. 最后运行 apt-get -f 指令修复安装依赖的包:
$ sudo apt-get -f install
  1. 更新系统默认使用的JDK版本,如果你的系统安装了多个版本的JDK,可以通过下面的指令执行切换,会弹出可选的JDK版本,根据你的需要选择对应的版本就可以了:
$ sudo update-alternatives --config java
$ sudo update-alternatives --config javac

2.安装所需要的工具包

Ubuntu 14.04

我们编译过程中会用到下面的依赖包,执行如下指令统一安装:

$ 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 ccache \
  libgl1-mesa-dev libxml2-utils xsltproc unzip

3.设置源码编译输出路径

默认情况下,编译好的系统源码会在源码所在目录的out文件夹下,
如果你希望调整输出目录的路径,可以执行下面的指令指定输出目录:​

$ export OUT_DIR_COMMON_BASE=<path-to-your-out-directory>

4.设置USB接口访问设备

在linux下,默认情况是不允许普通用户直接通过USB接口来访问设备的.

推荐方法是以根用户身份在 /etc/udev/rules.d/51-android.rules 路径创建文件。

我们可以通过如下指令来实现( 注意用你的系统username替换指令中的 ):

$ wget -S -O - http://source.android.com/source/51-android.rules | sed "s/<username>/$USER/" | sudo tee >/dev/null /etc/udev/rules.d/51-android.rules; sudo udevadm control --reload-rules

优化编译环境(可选)

设置ccache

我们可以自由选择是否开启ccache编译工具。

ccache是一个高速编译缓存工具,它通过将头文件高速缓存到源文件之中而改进了构建性能,因而通过减少每一步编译时添加头文件所需要的时间而提高了C\C++的构建速度。

从编译的全过程来看,不使用ccache的情况下,编译过程中会多次解析相同的头文件,浪费了处理器周期,更重要的是浪费了开发者的时间,因为他们要等待这一过程的完成。在一个团队中,这一影响可能会更为明显,因为团队成员可能会反复编译与解析相同的头文件。

所以,一般对于专门用来编译系统的服务器或是大容量的生产环境,这个功能比较有用,它可以加速重新编译的速度。

注意:如果你只是个人开发者,不是专门的编译服务器,不需要进行增量构建的话,那么使用ccache可能会因为高速缓存缺失而降低你的构建速度。

开启ccache

要开启ccache,需在源码树的根路径下执行下面的指令:

$ export USE_CCACHE=1
$ export CCACHE_DIR=/<path_of_your_choice>/.ccache
$ prebuilts/misc/linux-x86/ccache/ccache -M 50G

缓存的大小一般设置为50G-100G

接着在 .bashrc (或者etc/profile)中添加下面的指令

$ export USE_CCACHE=1

默认情况下,缓存会存在home根目录的~/.ccache中,但是如果你使用的是NFS或者其他的非本地文件系统,那么你同样需要在.bashrc指定缓存目录地址。

当编译的Android系统是4.0.x或者更老的版本,ccache的缓存路径会有所不同

$ prebuilt/linux-x86/ccache/ccache -M 50G

这个设置会一直存储在CCACHE_DIR中。

在Linux上,你可以通过以下指令开启对ccache的监听:

$ watch -n1 -d prebuilts/misc/linux-x86/ccache/ccache -s

下载源码

编译环境配置好之后,我们就可以开始下载我们的源码了

安装Repo

Repo是google用python写的一个脚本工具,Android使用git作为代码管理工具,一个Android系统由N多个git库构成,如果手动进行一个个下载,那简直是一件非常痛苦的事,而repo就是用来对这些git库进行维护管理跟下载的。

通过Repo工具,我们可以轻松地完成Android系统源码的下载。

1.在系统home根路径下创建bin目录并且添加到path路径中:
#创建bin目录
$ mkdir ~/bin

#把bin目录的路径添加到PATH中
$ PATH=~/bin:$PATH
2.下载repo工具并设置其可执行
#curl是个开源文件传输工具,在这里是把远程的repo文件下载到指定的~/bin/repo路径
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo

#修改repo对所有人可执行
$ chmod a+x ~/bin/repo

初始化Repo客户端

1.创建一个空目录用来存放我们的Android系统源码,名字自己随便定
#创建名为WORKING_DIRECTORY的目录
$ mkdir ANDROID_SOURCR_DIRECTORY

#进入到创建的目录中
$ cd ANDROID_SOURCR_DIRECTORY
2.初始化repo仓库

从主干master下载源码,目前最新版本

$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest

如果需要下载某个特定版本系统的分支,可以在上述命令后加-b 版本分支号,这里我指定Android 8.0的版本分支

$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-8.0.0_r15

具体的版本分支号可以到这个地址查看(需要翻墙):
Android系统个版本分支号

3.同步源码到本地

这时执行sync指令便可以自动下载源码到本地了

$ repo sync

使用国内镜像下载源码

由于各种你懂得原因,以上下载源码部分我选择了国内的镜像进行下载,就是这里:

清华大学的镜像站
有下载上的问题可以参照页面上的描述对上面的指令稍作调整就可以,站点上写得更加详细,我这边并没有遇到这些问题于是就暂且略过。

根据网速的不同,一般一天之内就能够下载完毕。

对于下载下来的源码,我们并不能直接刷到我们的目标设备上或者是使用模拟器运行,我们必须对源码进行编译生成对应的image二进制镜像文件。


源码编译

首先我们通过命令行进入到源码目录中,我这里目录的名称是ANDROID_SOURCR_DIRECTORY

$ cd ANDROID_SOURCR_DIRECTORY

清空输出目录

为了确保我们编译生成的文件不受之前build构建的文件影响,我们在源码目录中执行下面的指令,该指令会清空out输出目录中的所有文件

$ make clobber

设置编译环境

首先我们通过源码build目录中的 envsetup.sh 脚本文件初始化我们的编译环境,执行

$ source build/envsetup.sh

$ . build/envsetup.sh

这两个指令的效果是一样的,会初始化一些有用的命令工具

我们后面执行的一些指令必须在初始化 envsetup之后才能执行

选择编译目标

接着我们通过 lunch 指令来选择我们需要编译的目标执行lunch指令

$ lunch

会弹出可选目标项:

所有的构建目标由BUILD-BUILDTYPE的形式组成,BUILD对应codename。

这是官方提供的一份对照表:

DeviceCode nameBuild configuration
Pixel XLmarlinaosp_marlin-userdebug
Pixelsailfishaosp_sailfish-userdebug
HiKeyhikeyhikey-userdebug
Nexus 6Pangleraosp_angler-userdebug
Nexus 5Xbullheadaosp_bullhead-userdebug
Nexus 6shamuaosp_shamu-userdebug
Nexus Playerfuguaosp_fugu-userdebug
Nexus 9volantis (flounder)aosp_flounder-userdebug
Nexus 5 (GSM/LTE)hammerheadaosp_hammerhead-userdebug
Nexus 7 (Wi-Fi)razor (flo)aosp_flo-userdebug
Nexus 7 (Mobile)razorg (deb)aosp_deb-userdebug
Nexus 10mantaray (manta)full_manta-userdebug
Nexus 4occam (mako)full_mako-userdebug
Nexus 7 (Wi-Fi)nakasi (grouper)full_grouper-userdebug
Nexus 7 (Mobile)nakasig (tilapia)full_tilapia-userdebug
Galaxy Nexus (GSM/HSPA+)yakju (maguro)full_maguro-userdebug
Galaxy Nexus (Verizon)mysid (toro)aosp_toro-userdebug
Galaxy Nexus (Experimental)mysidspr (toroplus)aosp_toroplus-userdebug
Motorola Xoom (U.S. Wi-Fi)wingrayfull_wingray-userdebug
Nexus Ssoju (crespo)full_crespo-userdebug
Nexus S 4Gsojus (crespo4g)full_crespo4g-userdebug

BUILD_TYPE 对照表:

构建类型用途
user有限的访问权限,主要用于发布正式产品,没有root跟调试权限
userdebug跟user类型差不多,但是多了root跟debug调试权限
eng拥有各种调试工具的开发版设置,拥有root跟debug权限

如果作为开发使用的话,我们一般都是选 -eng

这里我自己是准备在模拟器上运行编译的image镜像,并且我电脑的cpu是intel x64的,所以我选择了 7. aosp_x86_64-eng

我们可以根据自己的需要选择对应的cpu类型。

注意:我们知道,Android官方的模拟器速度很慢,Intel特意提供了一个叫HAXM的虚拟硬件加速技术,全称为:Intel Hardware Accelerated Execution Manager.

只要你的CPU是intel的产品并且支持VT(virtualization Technology)就可以使用HAXM技术将你的模拟器的速度提升至真机的水平。

目前Intel只提供了windows版和MAC版,Linux系统只有通过安装KVM来达到这个效果。

安装KVM

首先我们检测下自己的cpu是否支持 hardware virtualization(硬件虚拟化)

$ egrep -c '(vmx|svm)' /proc/cpuinfo

输出的值如果是大于0的,则表明你的cpu支持

如果你使用的是vmware虚拟机安装的linux,注意要设置下虚拟机的cpu来支持硬件虚拟化,先关闭虚拟机,然后右键虚拟机 -> 设置,选中cpu,勾选虚拟化Intel-VT项,这样就能支持KVM了。

对于Ubuntu 10.0.4以上的版本,我们通过下面的指令安装KVM即可

$ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils

如果在安装KVM的过程中有什么疑问的话,可以访问下面这个网址查找方法:https://help.ubuntu.com/community/KVM/Installation

这样,在编译完目标intel cpu的镜像文件后,我们运行模拟器就会自动进行加速了。

编译源码

好了,一切就绪,我们可以开始编译我们的源码了,
我们在源码路径下通过 make -jN 指令来进行源码编译,这里的N一般建议设置为cpu核心线程数的1-2倍。

$ make -j4

接下来我们只要等待源码编译完成就可以了~

运行编译出的image镜像

经过漫长的等待,我们的源码终于编译结束了,是时候来运行编译出的image镜像了。

这时我们只要在源码目录下执行 emulator 指令即可运行模拟器

$ emulator

第一次启动时间可能会有点长,耐心等待即可。

注意:如果你的命令行窗口关闭重开了,那emulator指令可能会提示找不到命令,我们可以在源码根目录环境下,通过envsetup.sh重新初始化命令,运行lunch指令选择编译目标,这个时候你再运行emulator就不会提示找不到指令了(每次关闭命令行窗口都需要重新运行如下指令才能执行emulator)

$ source build/envsetup.sh
$ lunch
$ emulator

运行image镜像时可能会出现的问题:

  1. 如果在执行emulator时提示emulator: WARNING: system partition size adjusted to match image file (2550 MB > 200 MB),指定大于需要的内存大小就ok啦~

    $ emulator -partition-size 2660
    
  2. 如果在执行emulator时提示libGL error: unable to load driver: swrast_dri.so这种提示,则需要更改一下启动emulator时使用的libstdc++库:

    $ cd ~/ANDROID_SOURCR_DIRECTORY/prebuilts/android-emulator/linux-x86_64/lib64/libstdc++/
    $ mv libstdc++.so.6 libstdc++.so.6.bak
    $ ln -s /usr/lib/x86_64-linux-gnu/libstdc++.so.6 libstdc++.so.6
    
    #如果不知道自己虚拟机上lib库的位置,可使用命令查找
    $ locate libstdc++.so.6
    

到此,我们的源码就编译完毕啦~