在Mac OS X上编译Android ROM

Sun 06 December 2015

在Mac OS X上编译Android ROM

在Linux上编译Android的文章已经很多了,但Mac上编译的却很少。本文完整的演示如何在Mac OS X上编译出一个给Galaxy Nexus使用的4.3.1的ROM出来。使用的Mac系统版本是10.11

背景

我们在编译Android源码的时候,可以编译出3种类型的版本:

  1. Eng: 工程版, 有root权限,可以调试任意进程, adb调试默认开启
  2. User: 编译final release版本使用
  3. UserDebug: 和User版差不多, 可以调试任意进程, adb调试默认开启

我们选择Eng版进行编译,模拟器默认就是这个版本。编译这个版本的目的为了debugActivityThread和系统服务。

准备

  1. 准备文件系统
  2. 下载代码和二进制文件
  3. 安装必要的软件

准备文件系统

Android的编译需要 大小写敏感 的文件系统, 而Mac用户通常使用的是大小写不敏感的。如果自己有USB3.0或者Thunderbolt接口的外置存储,可以在外置存储上分出一个卷来格式化成Mac的日志式大小写敏感的文件系统。如果没有的话,我们利用稀疏文件创建出一个虚拟的磁盘。下面介绍后者:

hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 140g ~/Downloads/android.dmg

实际创建出来的文件多了一个后缀: android.dmg.sparseimage。为了方便(ccache也放在这个上面)我创建出140GB,实际在磁盘上是没有这么大的(稀疏文件)。 我把这个虚拟磁盘创建在Downloads目录,因为我的TimeMachine排除了这个目录。

为了方便mount和umount,我们在~/.bash_profile(相当于Linux的.bashrc)里面加上两个函数:

function mountAndroid { hdiutil attach ~/Downloads/android.dmg.sparseimage -mountpoint /Volumes/android; }
function umountAndroid() { hdiutil detach /Volumes/android; }

下载Android源码

从官方下载代码请参照: https://source.android.com/source/downloading.html

从第三方的镜像站可以参照我的另一篇博客: http://jksoftcn.com/androidyuan-ma-jing-xiang-zhan-de-cao-zuo.html

下载前先mount上虚拟磁盘:

source ~/.bash_profile
mountAndroid
cd /Volumes/android/
mkdir -p work/code
mkdir cache
cd work/code
ulimit -S -n 1024
export USE_CCACHE=1
export CCACHE_DIR=/Volumes/android/cache

上面的最后三条命令也建议加到~/.bash_profile里面去。

假设我们的Mac已经生成了ssh密钥,且对应的公钥已经加到镜像站的.ssh/authorized_keys文件中。从镜像站(android@android.jksoftcn.com:mirror)拉取代码:

mkdir ~/bin
PATH=~/bin:$PATH
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
sed -i.bak 's/https:\/\/gerrit.googlesource.com\/git-repo/android@android.jksoftcn.com:mirror\/git-repo/g' ~/bin/repo

上面最后一个命令是修改repo,让其检测升级的时候不被 GFW 墙。

repo init -u android@android.jksoftcn.com:mirror/platform/manifest -b android-4.3.1_r1

接下来下载代码。下载代码默认是4线程的,如果镜像站允许,自己的磁盘也够快,建议用sync -j8或更多的线程。

代码下载完了,我们还要下载一些闭源的文件:

https://developers.google.com/android/nexus/drivers#maguro

在上面这个网页上,我们找到Galaxy Nexus (GSM/HSPA+) binaries for Android 4.3 (JWR66Y)的驱动文件并下载:

curl https://dl.google.com/dl/android/aosp/broadcom-maguro-jwr66y-5fa7715b.tgz > broadcom-maguro-jwr66y-5fa7715b.tgz
curl https://dl.google.com/dl/android/aosp/imgtec-maguro-jwr66y-b0a4a1ef.tgz > imgtec-maguro-jwr66y-b0a4a1ef.tgz
curl https://dl.google.com/dl/android/aosp/invensense-maguro-jwr66y-e0d2e531.tgz > invensense-maguro-jwr66y-e0d2e531.tgz
curl https://dl.google.com/dl/android/aosp/nxp-maguro-jwr66y-d8ac2804.tgz > nxp-maguro-jwr66y-d8ac2804.tgz
curl https://dl.google.com/dl/android/aosp/samsung-maguro-jwr66y-fb8f93b6.tgz > samsung-maguro-jwr66y-fb8f93b6.tgz
curl https://dl.google.com/dl/android/aosp/widevine-maguro-jwr66y-c49927ce.tgz > widevine-maguro-jwr66y-c49927ce.tgz

逐一解压执行,例如:

tar zxvf broadcom-maguro-jwr66y-5fa7715b.tgz
./extract-broadcom-maguro.sh

按Enter查看授权, 按q退出查看,输入I ACCEPT回车接收授权。

最后设置一下ccache的大小:

prebuilts/misc/darwin-x86/ccache/ccache -M 50G

安装必要的软件

必要的软件包含:

  • JDK 1.6
  • Xcode
  • Perl的Switch模块

Android 4.3.1对JDK的要求是JDK 1.6(在Linux上是要求Sun的JDK 1.6)。在Mac上本就不存在OpenJDK,因此我们要安装的是Sun的,我们从Apple官网的这个地址就可以下载到:

https://support.apple.com/kb/dl1572?locale=zh_CN

这个虚拟机安装到的位置在/Library/Java/JavaVirtualMachines/1.6.0.jdk/

另外我们还要安装一个perl的库(可能在Mac OS 10.8上不需要):

sudo cpan
install Switch

如果不安装在编译过程中会出现这样的错误:

Can't locate Switch.pm in @INC (you may need to install the Switch module)

在Ubuntu下这个问题这样解决:

sudo apt-get install libswitch-perl

最重要的是安装Xcode,Xcode我们从App Store安装最新版本的。但4.3.1的代码最高只支持10.8版本的SDK,显然最新的Xcode里面是没有的。所有我们还要下载一个旧版本的Xcode。根据系统的对应关系,我们下载这个版本:

http://adcdownload.apple.com/Developer_Tools/xcode_5.1/xcode_5.1.dmg

这个版本的是不需要安装的(也没法安装),我们只要打开dmg文件mount上后执行下面的复制命令:

cp -R /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs

这一步非常重要,否则一编译就出错!

编译

这是一个漫长的过程,是否成功取决于前面的准备是否充分。 时间长短主要取决于CPU,在单路E5-1650v3的工作站上编译5.0,make -j20大概45分钟左右。

加载环境设置:

source build/envsetup.sh
lunch

You're building on Darwin

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_x86-eng
     3. aosp_mips-eng
     4. vbox_x86-eng
     5. aosp_deb-userdebug
     6. aosp_flo-userdebug
     7. full_tilapia-userdebug
     8. mini_armv7a_neon-userdebug
     9. mini_mips-userdebug
     10. mini_x86-userdebug
     11. full_mako-userdebug
     12. full_maguro-userdebug
     13. full_manta-userdebug
     14. full_toro-userdebug
     15. full_toroplus-userdebug
     16. full_arndale-userdebug
     17. full_panda-userdebug

Which would you like? [aosp_arm-eng]

我们要编译的是给Galaxy Nexus用的eng版rom,这里没列出,但可以直接输入full_maguro-eng。 也可以不显示菜单直接选:lunch full_maguro-eng

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=4.3.1
TARGET_PRODUCT=full_maguro
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a-neon
TARGET_CPU_VARIANT=cortex-a9
HOST_ARCH=x86
HOST_OS=darwin
HOST_OS_EXTRA=Darwin-15.0.0-x86_64-i386-64bit
HOST_BUILD_TYPE=release
BUILD_ID=JLS36I
OUT_DIR=out
============================================

确认一下是否选对了,maguro就是Galaxy Nexus的硬件代号。没有问题就可以开始编译了。

make -j6

我的MacBook Pro比较老,是双核四线程的i5,我用6个线程同时编译。

漫长的等待,看system.img创建出来了,就是成功编译出来了。

编译完成

刷rom

比Linux上少一个USB权限的步骤

手机关机,按住音量上下两个键不松开,再按电源键,开机时在震动后全部松开。进入fastboot模式。

如果手机之前没有解锁过,先解锁:

fastboot oem unlock

接下来执行刷rom:

fastboot flashall -w

如果不出意外,手机在重启后就进入新的rom了。去设置的关于里面确认一下这个Eng版本。

Eng版的用途

我们编译这个ROM并不是为了玩,官方已经给我们提供了编译好的ROM,况且这个Eng版的ROM也不适合使用。我们使用这个版本的ROM主要的目的是为了可以调试Android的Framework(包括系统服务),Java层和Native的都可以调试。

调试Framework网上的老教程都是叫你用Eclipse。如果你想用Eclipse请找那些文章。

调试Framework的Java我们使用IntelliJ IDEA,并且Android的源码已经提供了这方面的支持。先编译一个小工具:

cd development/tools/idegen/
mm
croot

利用小工具生成Intellij IDEA的工程:

development/tools/idegen/idegen.sh

然后就多了一个android.ipr文件,用Intellij IDEA打开。漫长的索引结束后,就可以attach到Galaxy Nexus上的任意Android进程了。

编译完成后out目录对我们很重要,ROM在这个目录下面。除次还有其他的东西:

  • out/host,和我们Mac系统有个的输出
  • out/target, 和Galaxy Nexus有关的输出

其中out/target/product/maguro/symbols这个目录非常重要,可以用于gdb调试Android的native代码。

胜利来之不宜,没事别手贱执行make clean

在这个编译的基础上,我们还可以编译修改版的aapt,修改版的dx。

总结

Mac上编译Android ROM和Linux上的细节有些差异,但基本流程是一致的。普通开发者编译rom可以更深入的了解Android系统,有的时候出现诡异的问题,光看源码还是不够,debug才能发现问题。

Category: Android Tagged: Android Mac ROM Framework

comments

Page 1 of 1