Compile Android Source on Mac OS X

在我看来,学习 Android 的一个有效途径就是阅读它的源代码,尽管市面上有各种各样的宝典、秘籍,但能从根源上把问题讲得透透彻彻的少之又少[推荐1]。我曾经在2010年编译并走读过它部分代码,但相比它浩瀚的代码,做的功课只是九牛一毛。

这段时间,我重新拾起丢掉的任务,计划在 MacBook Pro 走读代码,为了配合验证观点,很有必要对源代码加些注释,修改些代码。所有的这一切首先要做到将原生的 Android 源码编译通过。

背景介绍

我的 MBP 操作系统版本是 Mac OS X Mountain Lion (10.8.2),原生的 Python 和 GCC 等程序比较老旧,为此,通过 MacPorts,我还安装了它们的最新版本。因此,我的系统中,存在多个版本的 Python、GCC、Bison等。

上面这种情况在编译 Android 源代码时造成了不必要的麻烦,最新的软件,特别是编译程序,固然可以让我体验到新的 feature,但是它往往在兼容性上存在这样或那样的问题。特别是对于采用 C 的项目,由于历史原因,标准化程度不高,编译系统的每次变动,都意味着它可能编译失败。

使用 Python 2.7

用来操作 Android 代码仓库的 repo 工具是使用 Python 编写的,但它还不支持 Python 3.x,所以如果使用 MacPorts 安装了多个版本的 Python,那么需要留意系统正在使用的Python版本,通过以下方式可以查看:

xuhj@mac:/Volumes/HDD0/android-src$ port select --list python
Available versions for python:
	none
	python25-apple
	python26-apple
	python27 (active)
	python27-apple
	python32
	python33

如果当前使用的是 Python 3.x,那么可以通过如下方式进行调整(假如要使用 Python27):

xuhj@mac:/Volumes/HDD0/android-src$ sudo port select --set python python27
Selecting 'python27' for 'python' succeeded. 'python27' is now active.

至此,Python 的环境设置完成。

使用 Java 6

我在Mac上安装了Oracle的JDK 1.7,但我并不清楚Android是否可以支持它,为了保险起见,我得检查Java环境,然后确认它使用 OS X 原生的 1.6:

xuhj@mac:/Volumes/HDD0/android-src$ /usr/libexec/java_home -V
Matching Java Virtual Machines (3):
   1.7.0_13, x86_64:	"Java SE 7"	/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home
   1.6.0_43-b01-447, x86_64:	"Java SE 6"	/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
   1.6.0_43-b01-447, i386:	"Java SE 6"	/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home

/Library/Java/JavaVirtualMachines/jdk1.7.0_13.jdk/Contents/Home

我需要选择Jdk1.6

xuhj@mac:/Volumes/HDD0/android-src$ export JAVA_HOME=$(/usr/libexec/java_home -v 1.6)

确认

xuhj@mac:/Volumes/HDD0/android-src$ javac -version
javac 1.6.0_43

自此,Java 的环境也设置完成了。

安装 gmake 3.81

因为 Google 在官方网站明确说明gmake 3.82存在问题,必须要安装3.81,因此接下来就是按照它的建议,按部就班地安装,这里不再赘述。

获取 Android

现在获取Android源代码,此时我们获取master分支的代码:

xuhj@mac:/Volumes/HDD0/android-src$ repo init -u https://android.googlesource.com/platform/manifest

接着,别着急编译,我们需要一个稳定的分支,它应该是官方认可的、没有问题的,可以从官方找到这些,然后进入到源代码目录,执行切换

xuhj@mac:/Volumes/HDD0/android-src$ repo init -b android-4.2.2_r1

如果以后你想看到 Android 整个项目的最新代码,还可以切换回master

xuhj@mac:/Volumes/HDD0/android-src$ repo init -b master

至此,Android 源码准备完毕。

支持 OS X 10.8:

编译之前,首先要选定目标:

xuhj@mac:/Volumes/HDD0/android-src$ lunch full-eng

可是,这样看到一个问题:

build/core/combo/HOST_darwin-x86.mk:62: *****************************************************
build/core/combo/HOST_darwin-x86.mk:63: * Cannot find SDK 10.6 at /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.6.sdk
build/core/combo/HOST_darwin-x86.mk:65: * If you wish to build using higher version of SDK,
build/core/combo/HOST_darwin-x86.mk:66: * try setting BUILD_MAC_SDK_EXPERIMENTAL=1 before
build/core/combo/HOST_darwin-x86.mk:67: * rerunning this command
build/core/combo/HOST_darwin-x86.mk:69: *****************************************************
build/core/combo/HOST_darwin-x86.mk:70: *** Stop.. Stop.

毕竟 OS X 不是编译 Android 的主流平台,所以像 OS X 这样一年一更新的系统,Android 显得不够给力,不过没有关系,就按照它的提示操作。

xuhj@mac:/Volumes/HDD0/android-src$ export BUILD_MAC_SDK_EXPERIMENTAL=1

至此,操作系统准备完毕。

解决 WebKit

编译了很久很久,就当以为就这么平静地结束时,问题发生了。

external/webkit/Source/WebCore/xml/XPathParser.cpp: In member function ‘WebCore::XPath::Expression* WebCore::XPath::Parser::parseStatement(const WTF::String&, WTF::PassRefPtr, WebCore::ExceptionCode&)’:
external/webkit/Source/WebCore/xml/XPathParser.cpp:480:39: error: too many arguments to function ‘int WebCore::XPath::xpathyyparse()’
out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/XPathGrammar.hpp:106:5: note: declared here
make: *** [out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/Source/WebCore/xml/XPathParser.o] Error 1
make: *** Waiting for unfinished jobs….

通过搜索,我在 android building,找到了类似的问题。追根溯源,找到问题的元凶是 bison 版本不兼容造成的。

那么,这个答案是不是也正对我的问题呢,接下来验证。首先,我知道 bison 在我的MBP 上存在两个版本,

xuhj@mac:/Volumes/HDD0/android-src$ /opt/local/bin/ --version
bison (GNU Bison) 2.7
由 Robert Corbett 和 Richard Stallman 编写。

版权所有 (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

上面那个是通过 MacPorts 安装的,还有一个是系统自带的:

xuhj@mac:/Volumes/HDD0/android-src$ /usr/bin/bison --version
bison (GNU Bison) 2.3
Written by Robert Corbett and Richard Stallman.

Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

那么现在使用的是哪个呢?

xuhj@mac:/Volumes/HDD0/android-src$ which bison
/opt/local/bin/bison

很好,正在使用2.7,可以确认它是问题的根源了。接下来打上补丁,但可惜无法自动完成,必须得手工来做。搞完了这些,再编译,一切顺利。

如果嫌打补丁麻烦,可以使用我的patch文件,也可以尝试着卸载掉MacPorts的bison,最后也能编译过去。

寻找 emulator

如果你看到了这里,并且也做了上面的那个补丁,并且也编译完成了,那么很遗憾告诉你,你还不能在 Mac 上运行 Android 模拟器,因为你找遍 out 目录,都没有一个叫做 emlator 的文件。

在开始编译的最初一瞬间,它会告诉你,但很多人,包括我自己都忽略了它:

Checking build tools versions…
build/core/main.mk:165: ****************************************
build/core/main.mk:166: * gcc is linked to llvm-gcc which will *
build/core/main.mk:167: * not create a useable emulator. *
build/core/main.mk:168: ****************************************

所以,大家空欢喜一场了,~_~


[1] 罗升阳.Android系统源代码情景分析[M].北京:电子工业出版社,2012

Leave a comment

Your comment