aosp编译

一、编译步骤

1.1 下载源码

如果网络允许,可以从Google直接下载源码。本节介绍如何使用国内的镜像源下载,清华源由于目前限速,所以选择中科大源。

首先下载谷歌的源码管理工具repo,该工具源于depot_tool,可以直接下载depot_tool并在PATH下建立符号链接,也可以仅下载repo的代码,这里以后者为例。

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
## 如果上述 URL 不可访问,可以用下面的:
## curl -sSL  'https://gerrit-googlesource.proxy.ustclug.org/git-repo/+/master/repo?format=TEXT' |base64 -d > ~/bin/repo
chmod a+x ~/bin/repo

建立源码目录并进入,以android 10代码为例。

mkdir android-10_r1 && cd android-10_r1

初始化源码仓库,其中-b选项用于设定要同步的Android版本,这里以Android 10的第一个发行版为例。完整的可选参数在这里。类似于git,这一步执行完后会在该目录下生成.repo文件。

repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-10.0.0_r1
## 如果提示无法连接到 gerrit.googlesource.com,可以编辑 ~/bin/repo,把 REPO_URL 一行替换成下面的:
## REPO_URL = 'https://gerrit-googlesource.proxy.ustclug.org/git-repo'

最后开始同步代码,选项-j用于表示同步的线程数,建议不要选择太大,4个线程足够,线程数太多可能会有同步失败的可能。

repo sync -j4

1.2 编译环境部署

硬件要求:

64位的操作系统只能编译 2.3.x 以上的版本,如果你想要编译 2.3.x 以下的,那么需要32位的操作系统.

磁盘空间越多越好,至少在 100GB 以上;如果你想要在是在虚拟机运行linux,那么至少需要16GB的 RAM/swap.

软件要求:

  1. 操作系统要求

在AOSP开源中,主分支使用Ubuntu长期版本开发和测试的,因此也建议你使用Ubuntu进行编译,下面我们列出不同版本的的Ubuntu能够编译那些android版本:

Android版本

编译要求的Ubuntu最低版本

Android 6.0 至 AOSP master

Ubuntu 14.04

Android 2.3.x 至 Android 5.x

Ubuntu 12.04

Android 1.5 至 Android 2.2.x

Ubuntu 10.04

  1. JDK版本要求

除了操作系统版本这个问题外,我们还需要关注JDK版本问题,下面列出的不同Android版本的源码需要用到的JDK版本:

Android版本

编译要求的JDK版本

AOSP的Android主线

OpenJDK 8

Android 5.x 至 android 6.0

OpenJDK 7

Android 2.3.x 至 Android 4.4.x

Oracle JDK 6

Android 1.5 至 Android 2.2.x

Oracle JDK 5

更具体的可以参看:Google源码编译要求

// 安装 jdk8
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk

// 安装 jdk7
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-7-jdk

// 安装oracle jdk
sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java6-installer

// jdk版本切换
sudo update-alternatives --config java
sudo update-alternatives --config javac
  1. 其它要求

Google官方构建编译环境指南中已经说明了Ubuntu14.04,Ubuntu 12.04,Ubuntu 10.04需要添加的依赖(推荐使用ubuntu 14.04)

而Ubuntu16.04添加的依赖为:

sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib
sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386
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 libgl1-mesa-dev libxml2-utils xsltproc unzip m4
sudo apt-get install lib32z-dev ccache
  1. 下载硬件驱动程序(刷入到真机时使用)

我们从google下载的源码编译后不能直接的刷入到我们的手机上,主要就是因为我们需要将设备对应的驱动放到源码里面一起编译,google旗下的nexus产品的驱动你可以通过以下的链接下载到: https://developers.google.com/android/nexus/drivers 将对应的三个文件下载下来,解压得到sh文件并放到Android源码根目录下。然后在终端中分别执行上述三个sh文件,即可在源码根目录下的 vendor 文件夹下自动释放相应文件

1.3 编译

在使用Android源码之前,需要完整编译整个源码

进入Android源码根目录:

source build/envsetup.sh    // 初始化编译环境
lunch    // 指定此次编译的目标设备以及编译类型
export LC_ALL=C //加入到bashrc或者zshrc中
make [-j4]    // 开始编译,默认为编译整个系统,其中 -j4 代表的是编译的job数量为4,即线程数

lunch 的作用是选择选择编译目标,编译目标的格式为:BUILD-BUILDTYPE

BUILD 指的是特定功能的组合的特定名称,即表示编译出的镜像可以运行在什么环境

  • aosp(Android Open Source Project)代表Android开源项目

  • arm 表示系统是运行在arm架构的处理器上

  • arm64则是指64位arm架构处理器

  • x86 则表示x86架构的处理器

BUILD TYPE 则指的是编译类型,通常有三种:

  • user - 代表这是编译出的系统镜像是可以用来正式发布到市场的版本,其权限是被限制的(如:没有root权限,不能dedug等)

  • userdebug - 在user版本的基础上开放了root权限和debug权限

  • eng - 代表engineer,也就是所谓的开发工程师的版本,拥有最大的权限(root等),此外还附带了许多debug工具

我们平时常用的设备代码和编译目标:

设备型号

设备代码

编译目标

Nexus 5

hammerhead

aosp_hammerhead-userdebug

Nexus 6

shamu

aosp_shamu-userdebug

Nexus 5X

bullhead

aosp_bullhead-userdebug

Nexus 6P

angler

aosp_angler-userdebug

公司的小辣椒手机

pxa1908sl_tz-userdebug

更多参考:官方文档

可以在编译前修改源文件中的 ro.secure,避免以后在adb shell中无法 remount 的情况。

在文件 /build/core/main.mk 和 /build/core/build-system.html中,将 ro.secure = 1 改为 ro.secure = 0(两个文件中共有4个值)

二、单个编译编译

以反汇编作为case检测策略时,有时需要编译单个模块来获取汇编代码打补丁前后变化,常用指令如下。

编译指令

解释

m

在源码树的根目录执行编译

mm

编译当前路径下所有模块,但不包含依赖

mmm [module_path]

编译指定路径下所有模块,但不包含依赖

mma

编译当前路径下所有模块,且包含依赖

mmma [module_path]

编译指定路径下所有模块,且包含依赖

make [module_name]

无参数则表示编译整个Android代码

Tips:

  • 对于m、mm、mmm、mma、mmma这些命令的实现都是通过make方式来完成的;

  • mm/mmm 默认只会编译发生改变的部分,如果要编译模块的所有文件,需要 -B 选项

  • mmm/mm编译的效率很高,而make/mma/mmma编译较缓慢;

  • make/mma/mmma编译时会把所有的依赖模块一同编译,但mmm/mm不会;

  • 建议:首次编译时采用make/mma/mmma编译;当依赖模块已经编译过的情况,则使用mmm/mm编译

三、代码刷入实机

  1. 用USB将手机与PC连接;

  2. sudo adb reboot bootloader 进入fastboot模式

  3. 如果fastboot是锁定状态(屏幕下方有一个小锁),需要执行fastboot oem unlock

  4. 在 out/target/product/xxx 目录下执行 fastboot -w flashall(需要先执行 . build/envsetup.sh 设置必要的环境变量),会将目录下的所有 .img 文件烧录到手机中

fastboot 的常用命令:

/* 擦除分区 */
fastboot erase {partition}
// 例:
fastboot erase boot
fastboot erase system

/* 烧写指定分区 */
fastboot flash {partition} {*.img}
// 例:
fastboot flash boot boot.img
fastboot flash system system.img

/* 烧写所有分区 */
fastboot flashall
// 注意:此命令会在当前目录中查找所有img文件,将这些img文件烧写到所有对应的分区中,并重新启动手机

/* 重启手机 */
fastboot reboot
fastboot reboot-bootloader    // 重启到 bootloader 刷机用

四、remount

将修改后的 xxx.so 文件写入手机:

adb push out/target/product/pxa1908sl/system/lib/xxx.so /data/local/tmp/
adb shell
mount -o rw,remount /system     # 需要root权限
cp /data/local/tmp/xxx.so /system/lib/

关于无法remount的问题

检查系统的ro.secure是否为0

adb shell getprop | grep "ro.secure"

如果不是,修改代码makefile,在build/core/main.mk 和 build/core/build-system.html将其中的ro.secure = 1 改为 ro.secure = 0,再full build

Last updated

Was this helpful?