Ubuntu16.04编译android6.0源代码


http://zke1ev3n.me/2016/08/25/Ubuntu16-04%E7%BC%96%E8%AF%91android6-0%E6%BA%90%E4%BB%A3%E7%A0%81/


因为最近经常编译android,每次都要去网上搜索教程,这里把自己编译的步骤记录下来,方便以后查询。

源码下载

安装git

安装好了后配置下用户名和邮箱地址。

1
2
3
$ sudo apt-get install git
$ git config --global user.name "Your Name"
$ git config --global user.email "you@example.com"

安装curl

1
$ sudo apt-get install curl

下载repo

repo是google为方便管理android源码编写的一系列python脚本。

1
2
$ mkdir ~/bin
$ PATH=~/bin:$PATH
1
2
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo

同步代码

创建源码目录:

1
2
$ mkdir android-6.0.1_r46
cd android-6.0.1_r46

使用repo init指定要同步的代码版本。你可以在这里找到目前所有android源码的版本:
https://source.android.com/source/build-numbers.html

1
$ repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r1

这里使用google的镜像服务器上同步代码,如果你没有翻墙工具或者下载很慢的话可以使用国内的源,比如清华的,像下面这样修改~/bin/repo中的REPO_URL。

1
REPO_URL = 'https://gerrit-google.tuna.tsinghua.edu.cn/git-repo'

然后同样使用repo init来执行同步的版本。

1
$ repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b android-6.0.1_r46

然后使用下面的命令下载源码。因为源码比较大,所以下载时间会很长,android6.0.1的代码大概有46G左右。repo支持断线重连,所以直接挂在哪里就可以了。

1
$ repo sync

编译源码

android源码编译有一些环境要求,具体可以查看下面的网址:
https://source.android.com/source/requirements.html

安装openjdk

我们这里编译的是android6.0.1,需要先安装openjdk。

1
2
3
$ sudo add-apt-repository ppa:openjdk-r/ppa  
$ sudo apt-get update   
$ sudo apt-get install openjdk-7-jdk

但是在日常使用中,我们更经常使用oracle-jdk,所以如果电脑上安装了其他版本的jdk的话,可以使用下面的命令来切换当前使用的jdk版本。

1
2
$ sudo update-alternatives --config java
$ sudo update-alternatives --config javac
安装依赖

不同的系统版本需要的依赖可以在这里找到:
https://source.android.com/source/initializing.html

但是这个网址上只有14.04需要的依赖,经过实验发现在16.04上不成功。下面是我在网上找到的16.04所需的依赖:

1
2
3
4
5
6
7
8
9
10
$ sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386
$ sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib
$ sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386
$ sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-dev
$ 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 lib32z-dev ccache
$ sudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4
修改源码

我在编译源码的过程中,编译到libartd.so时出现了如下错误:

1
clang: error: linker command failed with exit code

后来经过搜索,发现修改art/build/Android.common_build.mk文件中的:

1
ifneq ($(WITHOUT_HOST_CLANG),true)


1
ifeq ($(WITHOUT_HOST_CLANG),false)

然后重新编译即可。

开始编译

为了提高编译效率,设置编译器高速缓存。

1
2
$ echo export USE_CCACHE=1 >> ~/.bashrc
$ prebuilts/misc/linux-x86/ccache/ccache -M 50G

导入编译Android源码需要的环境变量和其他参数:

1
$ source build/envsetup.sh

使用lunch命令选择需要编译的目标:

1
$ lunch

我这里选择的是1。然后使用make命令开始编译。可以使用make -j 来设置参与编译的线程数量,一般来说设置为cpu核心数的两倍。可以使用如下命令查看当前电脑的cpu核心数量:

1
$ cat  /proc/cpuinfo

大概几个小时后,就可以编译成功了。使用emulator命令就可以启动编译好的模拟器。

1
$ emulator

如图:
Screenshot from 2016-08-25 15-05-34.png

启动模拟器

因为我们导入的环境变量在关闭shell后就失效了,所以我们不能直接用emulator命令来启动模拟器。每次启动模拟器前要先导入环境变量。

1
2
3
$ source build/envsetup
$ lunch #这里选择编译时选择的版本
$ emulator

运行android模拟器时,

emulator -avd test -no-skin -no-audio -no-window

  • ‘-no-skin’表示移除模拟按钮

  • ‘-no-audio’ 表示禁用音频

  • ‘-no-window’ 表示禁用图形窗口

模块编译

除了通过make命令编译可以整个android源码外,Google也为我们提供了相应的命令来支持单独模块的编译.

编译环境初始化(即执行source build/envsetup.sh)之后,我们可以得到一些有用的指令,除了上边用到的lunch,还有以下:

  • croot: Changes directory to the top of the tree.
  • m: Makes from the top of the tree.
  • mm: Builds all of the modules in the current directory.
  • mmm: Builds all of the modules in the supplied directories.
  • cgrep: Greps on all local C/C++ files.
  • jgrep: Greps on all local Java files.
  • resgrep: Greps on all local res/*.xml files.
  • godir: Go to the directory containing a file.

其中mmm指令就是用来编译指定目录.通常来说,每个目录只包含一个模块.比如这里我们要编译Launcher2模块,执行指令:

1
mmm packages/apps/Launcher2/

稍等一会之后,如果提示:

1
### make completed success fully ###

即表示编译完成,此时在out/target/product/gereric/system/app就可以看到编译的Launcher2.apk文件了.

重新打包系统镜像

编译好指定模块后,如果我们想要将该模块对应的apk集成到系统镜像中,需要借助make snod指令重新打包系统镜像,这样我们新生成的system.img中就包含了刚才编译的Launcher2模块了.重启模拟器之后生效.

一些模块位置:

  • Android系统自带的apk文件都在out/target/product/generic/system/apk目录下;
  • 一些可执行文件(比如C编译的执行),放在out/target/product/generic/system/bin目录下;
  • 动态链接库放在out/target/product/generic/system/lib目录下;
  • 硬件抽象层文件都放在out/targer/product/generic/system/lib/hw目录下.

编译SDK

有时候我们需要自己编译一个sdk,比如有时候需要使用系统隐藏的api,可以将源代码目录中隐藏api的@hide注解去掉,然后使用下面的命令编译。

1
make sdk

编译Nexus设备的镜像

更多的时候我们需要的不是使用模拟器,而是使用真机调试。这个时候我们可以在lunch命令中选择适用于Nexus设备的镜像。比如我这里选择的是使用于nexus5的aosp-hammerhead-userdebug, 这样直接编译出来的镜像刷入手机是无法成功使用的,因为没有驱动。所以我们需要到官网上下载对应的驱动。你可以在这里选择对应源码镜像版本的驱动:
https://developers.google.com/android/nexus/drivers

下载3个压缩包拷贝到源码目录,然后分别解压获得3个sh脚本,分别运行这3个脚本文件,在源码目录会出现一个vendor的文件夹,里面就包含了nexus5的驱动文件。
重新编译源码,如果你之前已经编译过一次,那么这次会很快完成。编译完成后,我们就可以刷入设备了。首先手机进入fastboot模式,可以使用音量上下键+电源键或者在连接到adb时使用”adb reboot bootloader”进入。然后电脑端进入到/out/host/linux-x86/bin目录,运行

1
$ ./fastboot -w flashall

就可以刷入了。刷入完成后手机会自动重启。这里的命令表示清空用户数据然后全部刷入,当然也可以只刷入一部分。

编译内核

android的源码目录下没有内核代码,需要自己手动下载。下载很简单,使用git clone即可。
在这里可以找到对应机型的内核版本:
https://source.android.com/source/building-kernels.html
这里可以找到更详细的信息:
https://android.googlesource.com/kernel/

比如我要编译的是nexus5的内核镜像。通过第一个网址我们可以知道它对应的内核版本为’kernel/msm’。在源码目录新建kernel目录,然后git clone。

1
2
$ mkdir kernel
$ git clone https://android.googlesource.com/kernel/msm.git #这一步需要代理

内核源代码大小大概有1个多G。clone完后进入msm目录,可以发现里面什么都没有,因为我们还没有选择分支。使用

1
$ git branch -a

来查看所有分支。如下图:
Screenshot from 2016-08-28 16-38-10.png

这里因为我们编译nexus5 6.0.1的内核,所以使用如下命令:

1
git checkout -b android-msm-hammerhead-3.4-marshmallow-mr2 remotes/origin/android-msm-hammerhead-3.4-marshmallow-mr2

然后配置一些环境变量:

1
2
3
4
$ export ARCH=arm
$ export SUBARCH=arm
$ export CROSS_COMPILE=arm-eabi-
$ make hammerhead_defconfig

然后使用

1
$ make

编译。编译成功后会在arch/arm/boot目录下生成一个zImage文件。将这个文件替换掉device/lge/hammerhead-kernel中的zImage。或者导出环境变量

1
$ export TARGET_PREBUILT_KERNEL="zImage文件路径"

然后使用

1
$make bootimage

重新编译boot.img。再刷入手机就可以了。


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值