Mac OS X 10.7下编译Android2.3.6源码以及su.c

第一次工作内容和折腾重合吧,因为资料比较分散,所以还是写点东西记录一下。

首先是包管理,Android官方推荐是macports——试用了一分钟后,我坚决地抛弃了它。
下文全部基于homebrew,属于一种第三方解决方案。
喜欢参考官方文档的推荐这里:http://source.android.com/source/initializing.html

一、安装homebrew,

$ ruby -e "$(curl -fsSkL raw.github.com/mxcl/homebrew/go)"

二、准备编译工具

# 安装一系列的安装包:
$ brew install git coreutils findutils gnu-sed gnupg pngcrush repo

# 下载一个gcc 4.2
$ brew install https://raw.github.com/Homebrew/homebrew-dupes/master/apple-gcc42.rb

# 在当前Shell使用gcc 4.2(xcode 4.3以后默认使用lvm,故此处修改默认编译器)
$ export CC=/usr/local/bin/gcc-4.2 && export CXX=/usr/local/bin/g++-4.2

# 现在需要创建一对符号链接,使“sed”和“find”的GNU版本得到应用:
$ ln -s /usr/local/bin/gfind /usr/local/bin/find && ln -s /usr/local/bin/gsed /usr/local/bin/sed

三、准备编译空间

# 因为安卓需要一个大小写敏感的磁盘分区,所以新建
$ hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg

编辑.bash_profile文件添加以下内容

# mount the android file image
function mountAndroid { hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android; }

# set the number of open file to be 1024
ulimit -S -n 1024

回到命令行,挂载并切入新分区目录

# 重新载入.bash_profile
$ source ~/.bash_profile
# 挂载新分区
$ mountAndroid
# 切换工作目录
$ cd /Volumes/android

四、下载源代码

# 随便起个名字就好
$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRECTORY
# 初始化repo为对应版本,这里使用2.3.6_r1
$ repo init -u https://android.googlesource.com/platform/manifest -b android-2.3.6_r1
# 等待吧,少年,这句命令要下载10个G的东西
$ repo sync

五、修改源代码以适应编译环境
首先确认SDK目录,之后的文件内对应路径需修改为此路径
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk

编辑文件external/qemu/Makefile.android
修改

LEOPARD_SDK := /Developer/SDKs/MacOSX10.5.sdk

改为:

LEOPARD_SDK := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk

编辑文件 build/core/combo/HOST_darwin-x86.mk
修改

sdk_105_root := /Developer/SDKs/MacOSX10.5.sdk

改为:

sdk_105_root := /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk

编辑文件 external/elfutils/config-compat-darwin.h
修改

static inline size_t strnlen (const char *__string, size_t __maxlen)
{
int len = 0;
while (__maxlen-- && *__string++)
len++;
return len;
}

改为:

#if 0
static inline size_t strnlen (const char *__string, size_t __maxlen)
{
int len = 0;
while (__maxlen-- && *__string++)
len++;
return len;
}
#endif

六、编译并排除其他错误

$ source build/envsetup.sh
$ lunch full-eng
$ make

七、修改并编译su

# 清楚垃圾
$ make clean
# 切换至su目录
$ cd system/extras/su/
# 备份一下文件
$ mv su.c su.c.bak
$ mv Android.mk Android.mk.bak
# 这里使用superuser.googlecode.com的源码
$ wget http://superuser.googlecode.com/svn/trunk/su/Android.mk
$ wget http://superuser.googlecode.com/svn/trunk/su/su.c
# 任意修改su.c
$ emacs su.c
# 编译su
$ cd ../../..
$ make su