Thinking
最近刚买了Mac,趁着新鲜感还在,多学习点东西,对自己的职业发展是有好处的.在公司里实习的这段时间,几乎每周都有经验分享,大多数都涉及Android Framework层的知识,鉴于编写Android Appilication也有一段时间了,是时候开始着手从源码上提高自己的水平了.于是有了这篇文章.
Preparing
首先还是从android官网入手,看看准备工作有哪些.
创建磁盘文件
由于Mac OS X系统在默认安装时,文件类型是大小写保留的(但不是大小写敏感),这种类型可能会造成git工作不正常,因此最好创建一块新磁盘,并将文件类型设置为大小写敏感的.
创建磁盘有两种方式:
LaunchPad->Disk Utility->New Image,如图所示.
打开Terminal,输入如下命令:
$ hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 50g ~/android.dmg
需要注意的地方:
- 如果编译的是和我一样的版本,则磁盘空间最好超过50GB,因为我编译完成后的总大小是41GB(不包括
.repo
文件夹); - 文件各种一定要选择Case-sensitive的;
如果在编译过程中遇到磁盘不够用的情况,可以先将android镜像umount,然后通过下面的命令行更改磁盘大小,最后再mount上.
$ hdiutil resize -size <new-size-you-want>g ~/android.dmg
- android官方提供有mount和umount的function,将它们paste到’~/.bash_profile‘(没有的话就touch一个),如下:
1 | # mount the android file image |
最后再Terminal里输入以下命令更新启动文件.
$ source ~/.bash_profile
安装JDK
android的编译不支持JDK8.0的编译环境,而我的机子装的都是最新版的JDK,因此只能再去官网下载JDK7.0并安装.官方提供的版本是jdk-7u71-macosx-x64.dmg.
安装完成后,可以到/Library/Java/JavaVirtualMachines
目录下查看目前安装的所有JDK版本.默认安装完成后,并不会自动地切换版本,需要手动进行.我参考了How to switch JDK version on Mac OS X这篇文章,在启动文件里设置了function,需要切换的时候直接输入下面的命令就可以了.
$ setjdk 1.* (*代表版本号,6/7/8,前提是你安装了相应的版本)
安装Xcode
前面说了,我机器上的所有软件都是官方最新的版本,Xcode也不例外,默认安装的Xcode版本是6.4,其中Command Line Tools的版本是6.4, Mac SDK版本是10.10/10.9.第一次编译Android的过程中,出现了如下问题:
1 | ... |
Google了一番,发现遇到这个问题的人少得可怜…不过在GoogleGroup上有人讨论了这个问题:libnativehelper/JNIHelp.cpp:28:10: fatal error: ‘string’ file not found,解决方案就是把Xcode降级到5.1.1,使用Mac SDK 10.8及Command Line Tools 5.1.1来编译.
随后就默默地去苹果的开发者论坛下载了Xcode_5.1.1.dmg,下载需要登陆开发者账号(不需要付费).下载并安装完成后,把Command Line Tools设置成了Xcode 5.1.1 (5B1008).
还有一种简便的做法是直接下载Mac SDK 10.8,然后将这个包放到/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
.
安装MacPorts
MacPorts和apt-get,yum,homebrew等软件一样,用于快捷安装应用程序.
访问官方网站,这里提供有dmg安装和源码安装两种方式,dmg就多说了,下载MacPorts-2.3.3-10.10-Yosemite.pkg,下一步下一步安装即可。安装MacPorts时间比较长,可能和国内的网络有一定关系…耐心等待即可.
安装完成后,将其添加到PATH路径里及启动文件里,打开~/.bash_profile
,添加:
$ export PATH=/opt/local/bin:$PATH
最后使启动生效:
$ source ~/.bash_profile
一切准备就绪后,通过MacPorts安装make,git和GPG:
$ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg
解除文件限制
Mac系统下默认只能同时打开1024个文件,而在进行Android源码编译时有可能会超出这个限制,因此需要解除这个限制.方法很简单,在~/.bash_profile
里添加一行:
# set the number of open files to be 1024
ulimit -S -n 1024
Getting the Source Code
以上一切准备就绪后,就可以开始源码的下载工作了.下载源码之前,需要同步repo,同时获取最新的android源码分支版本.
安装repo
Repo是一个辅助于Git管理Android版本及分支的工具.在安装repo前,需要新建一个文件夹~/bin(名字可随意定)
并把这个文件夹放到PATH环境变量里,然后我们就可以把repo下载到这个文件夹里.
$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo (执行此条命令需要FQ~)
$ chmod a+x ~/bin/repo
repo这个工具很小(24KB),但却是下载整个源码不可缺少的工具.下载完成后,建立一个放置android源码的目录,
$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRECTORY
然后通过repo init
将分支信息拉到本地:
$ repo init -u https://android.googlesource.com/platform/manifest
当然如果有其他国内的镜像的话可以用国内镜像代替,可参考同步、更新、下载Android Source & SDK from 国内镜像站这篇文章.
初始化的分支目录大小约为1.87MiB,之后会得到类似下面这样的目录:
1 | ... |
选择你想下载的android源码版本(我选择了android-5.1.1_r9),然后输入下面的命令进一步初始化该分支信息
$ repo init -u https://android.googlesource.com/platform/manifest -b android-5.1.1_r9
初始化工作完成后,下一步就是下载源码了.
下载Android源码
为了将Android源码下载到本地,通过代码同步当前的repo:
$ repo sync
下载源码的时间特别漫长,中途可能会发生断开连接的现象,不过并不要紧,此同步支持断点继传,但麻烦的是不知道什么时候会断开,为了解决这个问题,可以使用下面的shell来开启同步:
1 |
|
将上面的代码保存成get_android.sh
,放在下载的源码的根目录下,开始下载:
$ ./get_android.sh
下载完成android5.1.1-r9版本的repo后,会发现占用最大空间的不是源码,而是.repo
文件夹….repo
文件夹占用17GB,源码占用10GB.然后源码编译跟.repo
文件夹并没有什么关系,在空间有限的Mac系统里,不得不珍惜每一寸土地,因此可以大方地
$ rm -rf .repo/
最后保留10G的源码即可.接下来,挂载刚才创建的磁盘,并将源码移到磁盘目录下,
$ cd ~/bin/WORKING_DIRECTORY/
$ mountAndroid
$ mv ~/bin/WORKING_DIRECTORY/* /Volumes/android/
Compiling the Source Code
源码下载完成后,还需要做一些编译源码前的准备工作.我的编译环境如下表所示:
Mac OS X系统 | Mac OS X SDK | git | GnuPG | GNU Make | JDK | Command Line Tools |
---|---|---|---|---|---|---|
10.10.4 | 10.8 | 2.5.0 | 1.4.19 | 3.81 | 1.7.0_79 | 5.1.1(5B1008) |
编译环境过新很有可能导致编译失败.例如,我之前用的编译环境是MacOSX 10.10, JDK 1.8, Command Line Tools 6.4, 会出现上面提到的fatal error: 'string' file not found
的错误.为了修正这个错误,需要手动去调整Mac SDK版本.首先进入下面的目录查看是否安装了MacOSX10.8.sdk
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs
如果已经安装了,那就找到下面的文件,
/Volumes/android/build/core/combo/HOST_darwin-x86_64.mk
手动更改-DMACOSX_DEPLOYMENT_TARGET=
10.8,然后保存退出.
初始化
编译源码前需要初始化编译环境,进入源码根目录/Volumes/android/
,执行
$ source build/envsetup.sh
得到下面的提示:
1 | including device/asus/deb/vendorsetup.sh |
接下来选择编译目标,其中full
这个名字可以随意定,后面的-eng
表示附带了调试工具的开发者配置模式:
$ lunch full-eng
出现以下类似信息:
1 | ============================================ |
接下来就可以编译了:
$ make -jN
其中N代表同时进行的任务数.官方建议任务数设置为线程数的1~2
倍,比如我的机器是单CPU,四核,8线程,则最快的构建任务数是8~16
.
编译时间根据机器的性能不同而存在很大差异,在我的机子MacBook Pro (2.2 GHz Intel Core i7/16 GB 1600 MHz DDR3)
上编译了一个半小时.如果第一次编译失败,程序会接着在编译失败的地方继续编译,而不会从头再来.我第一次编译的时候硬盘空间不够,后来重新调整了容量再继续编译,只花了几分钟就编译完了.如果出现:
**make completed successfully (xx:xx (mm:ss))**
那么恭喜,编译成功了.
Running
由于没有真机,只能使用模拟器调试,因此输入下面的命令会自动打开模拟器:
$ emulator
至此整个android源码编译过程就完成了.