阅读 android 源码,应该是每个 android 开发者提升 技术最快的途径,如果感兴趣可以自己尝试编译一下 android 系统,本文编译环境是 ubuntu16.04 ,编译的 android 版本是 6.0 由于虚拟机配置比较低,编译器也比较慢,折腾了好几天。估计我的硬盘比我更辛苦,好了进入正题。
Google 采用 Git 对 AOSP 项目进行多仓库管理,所以需要先安装 git,git 的使用之前有记录过
123 |
sudo apt-get install git git config --global user.email “test@qq.com” git config --global user.name “tom” |
(参考科大源)
按照 Google 官方教程 https://source.android.com/source/downloading.html
将 https://android.googlesource.com/platform/manifest 替换为 git://mirrors.ustc.edu.cn/aosp/platform/manifest。
具体做法摘录如下(以防墙抽风):
1234567 |
mkdir ~/binPATH=~/bin:$PATHcurl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo## 如果上述 URL 不可访问,可以用下面的:## curl https://storage-googleapis.proxy.ustclug.org/git-repo-downloads/repo > ~/bin/repochmod a+x ~/bin/repo |
12 |
mkdir WORKING_DIRECTORYcd WORKING_DIRECTORY |
初始化仓库:
123 |
repo init -u git://mirrors.ustc.edu.cn/aosp/platform/manifest -b android-6.0.1_r62## 如果提示无法连接到 gerrit.googlesource.com,可以编辑 ~/bin/repo,把 REPO_URL 一行替换成下面的:## REPO_URL = 'https://gerrit-googlesource.proxy.ustclug.org/git-repo' |
有些时候 更换 REPO_URL 依然连接失败,没关系 多试几次
如果需要某个特定的 Android 版本(Android 版本列表):
1 |
repo sync |
接下来就是等了,这个过程比较慢 我大概用了一晚上 才下完源码。
注:
在下载过程中会出现很多问题,所以创建一个自动下载脚本,确保出错后自动执行 repo sync,要不睡一觉起来发下代码下载失败那多恼火。
先在 WORKING_DIRECTORY 下创建一个脚本 down.sh,代码如下:
1234567 |
#!/bin/bashrepo sync -j16while [ $? = 1 ]; do echo “======sync failed, re-sync again======” sleep 3 repo sync -j16done |
执行命令
12 |
chmod a+x down.sh./down.sh |
这样明天早上起来一看 代码就下完了。大概 50 多 G,所以如果用虚拟机编译的化,建议设置 100G 以上内存。
源码的文件夹中只有一个.repo 文件夹,这是正常的,等到所有源码下载完毕,其余文件夹就会出现,不要着急
下载完源码后,会发现代码有 50 多 G 其中有个隐藏文件夹.repo 他自己就有 40 多 G ,这个文件夹只跟代码同步有关,并不影响编译,果断删除,删除后源码只有 7G ,可以备份下源码
为了更快的安装软件,我们需要更换软件源为国内的软件源,这里推荐使用 Ubuntu 官方指定的国内软件源阿里云
1 |
sudo gedit /etc/apt/sources.list |
在文件最前面加入下面代码:
12345678910 |
deb http://mirrors.aliyun.com/ubuntu/ quantal main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ quantal-security main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ quantal-updates main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ quantal-proposed main restricted universe multiversedeb http://mirrors.aliyun.com/ubuntu/ quantal-backports main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ quantal main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ quantal-security main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ quantal-updates main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ quantal-proposed main restricted universe multiversedeb-src http://mirrors.aliyun.com/ubuntu/ quantal-backports main restricted universe multiverse |
1 |
sudo apt-get update |
1234567891011 |
sudo apt-get install -y git flex bison gperf build-essential libncurses5-dev:i386 sudo apt-get install libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-dev g++-multilib sudo apt-get install tofrodos python-markdown libxml2-utils xsltproc zlib1g-dev:i386 sudo apt-get install dpkg-dev libsdl1.2-dev libesd0-devsudo 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 lib32z-dev ccachesudo apt-get install libgl1-mesa-dev libxml2-utils xsltproc unzip m4sudo apt-get install git-core gnupg flex bison gperf build-essential zip curl zlib1g-dev gcc-multilib g++-multilib libc6-dev-i386 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z-dev ccache libgl1-mesa-dev libxml2-utils xsltproc unzip m4 |
Ubuntu 16.04 请务必使用上面的依赖,Ubuntu 16.04 需要的依赖和 Ubuntu 14.04 所需要的依赖是不同的,博主照着 Ubuntu 14.04 的依赖结果掉进大坑,详见后面的编译过程记录.
编译 android 源码 对应 android 版本对 ubuntu 版本有要求
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 |
Android 版本 | 编译要求的 Ubuntu 最低版本 | |
---|---|---|
AOSP 的 Android 主线 | OpenJDK 8 | |
Android 5.x 至 android 6.0 | OpenJDK 7 | |
Android 2.3.x 至 Android 4.4.x | Oracle JDK 6 |
更具体的可以参看:Google 源码编译要求
这里我编译的是 android6.0 用的是 openjdk7
Ubuntu 15.04 及之后的版本的在线安装库中只支持 openjdk8 和 openjdk9 的安装.因此,如果你想要安装 openjdk 7 需要首先设置 ppa:
12 |
sudo add-apt-repository ppa:openjdk-r/ppa sudo apt-get update |
然后再执行安装命令:
1 |
sudo apt-get install openjdk-7-jdk |
配置环境变量
打开/etc/profile 文件:
1 |
sudo gedit /etc/profile |
在末尾追加下面代码:
1234 |
export JAVA_HOME=/usr/lib/jvm/java-7-openjdk-amd64export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH |
修改了/etc/profile 文件需要重启才能生效,但使用下面命令可以在不重启的情况下在当前 bash 环境生效:
1 |
source /etc/profile |
有时候,我们需要编译不同版本的 android 系统,就可能使用不同的 jdk 版本.关于 jdk 版本切换,可以使用如下命令:
123 |
sudo update-alternatives --config javasudo update-alternatives --config javacsudo update-alternatives --config javap |
查询下 JDK 版本
1 |
java -version |
找到 WORKING_DIRECTORY/art/build/Android.common_build.mk 文件
1 |
ifneq ($(WITHOUT_HOST_CLANG),true) |
改为
1 |
ifneq ($(WITHOUT_HOST_CLANG),false) |
如果不修改这里,会遇到一个比较棘手的编译错误,
1 |
make:***[out/host/lnux-x86/obj/lib/libartd.so] Error 1 |
修改的目的是把 CLANG 这个编译选项关掉,详见后面的编译记录,百度搜狗都无解,这个错误只会在 Ubuntu16.04 上遇到,Ubuntu14.04 则不存在这个问题,这里卡了好几天
确保上述过程完成后,接下来我们需要初始化编译环境,命令如下:
1 |
source build/envsetup.sh |
lunch
控制台上会显示 选择 1
12345678910111213141516171819202122 |
/ou're building on LinuxLunch menu…pick a combo:1. aosp_arm-eng2. aosp_arm64-eng3. aosp_mlps-eng4. aosp_mlps64-eng5. aosp_x86-eng6. aosp_x86_64-eng7. aosp_deb-userdebug8. aosp_flo-userdebug9. full_fugu-userdebug10. aosp_fugu-userdebug11. mlnl_emulator_arm64-userdebug12. n_e_arm-userdebug13. mlnl_emulator_mlps-userdebug14. mlnl_emulator_x86_64-userdebug15. mlnl_emulator_x86-userdebug16. aosp_flounder-userdebug17. aosp_hammerhead-userdebug18. aosp_hammerhead_fp-userdebug19. aosp_shanu-userdebugrJhlch would you like? [aosp_arm-eng] | |
这里说一下 user userdebug eng
版本 | 描述 | |
---|---|---|
user | 用于正式产品 | |
userdebug | 和 user 类似,但是有 root 权限,并且可以调试,主要用于调试 | |
eng | 开发用的选项,配有额外的调试工具 |
如果编译后只在模拟器上运行,则 lunch 时选择:1
如果你想更深一步了解 lunch 该选哪一个,请参考下面的链接,根据第三列选择编译选项
https://source.android.com/source/running.html
通过 make 指令进行代码编译,该指令通过-j 参数来设置参与编译的线程数量,以提高编译速度.比如这里我们设置 8 个线程同时编译: 一般 google 推荐这个数字为 2 倍的 cpu 个数再加上 2,比如 4 核,就是 10
1 |
make -j8 |
关于 cpu 个数,可以用下面命令查看:
1 |
cat /proc/cpuinfo |
如果顺利,2 个小时左右 就可以看到编译成功了,不过 应该是不可能的
还有其他常用命令 你肯定能遇到 make clean,make update-api
编译的文件会在 out 目录下 编译成功里面会包含 system.img userdate.img ramdisk.img
1 |
emulator |
不出意外,你将运行起来一个 黏糊糊 热乎乎的 android6.0 没错 你看 他真的很丑。
编译源码 前前后后一共用了一个 多星期,其中不少坑 ,文章里写的也只是 在编译后能记录下来,还有些坑想想都丢人 一般人也不会犯。