Android 6.0 源代码编译实践

前阵子去上海参加 Android 开发面试,被问及了 Android 的基本原理、常用组件背后的实现机制、设计模式等问题,我都回答地不好。面试时,老司机们常常问我对知识点“背后的实现代码有没有看?”。于是我就想着,回来要把 Android 代码下下来,有针对性地学习。

本文记述了我从下载源代码到编译成功、导入 Android Studio 的过程。我所使用的系统为 Mac OSXAndroid 代码的分支是 android-6.0.0_r26

代码的下载

Android 的代码我是、从AOSP - 清华大学TUNA 镜像源这个国内的镜像下载。下载代码的具体方法在官方文档 Downloading the SourceAOSP - 清华大学TUNA 镜像源 中都有记述,我就不再赘述。我选择下载的分支是 android-6.0.0_r26

由于代码比较大,我使用我的下载机(Linux 系统)进行下载,待下载完成后导入 Mac OSX 进行后续操作。如何实现导入呢?

将代码文件夹拷贝到 ntfs 分区的移动硬盘失败。这是因为 ntfs 分区部分大小写,而代码目录中存在字母相同、大小写不同的文件,因此导入失败。(这一问题在后面 Mac OSX 中还会遇到。)

随后我对代码文件夹进行了压缩。压缩之后就能够随意拷贝了。在这里我推荐一种拷贝方式,就是直接用网线将两台机器相连对拷代码压缩包。这样速度非常快,也省得移动硬盘中转浪费时间。

Mac OSX 下的准备

压缩包拷过来之后,就该要解压、配置了。但是前文所说的大小写问题在这里又出现了。若将代码直接解压在 Mac 的文件系统中强硬编译将会报错。

创建映像文件

解决的方法是按照官方文档 Establishing a Build Environment 中的说明,建立一个区分大小写的映像文件,挂载后将代码解压进去,具体步骤不再赘述。

有一点需要强调的是,文档中创建的映像文件大小为 40GB,这在实际中不够,我编译完代码后就已经占用 46GB 了,因此我分配了 60GB 的大小。

JDK 版本

JDK 必须为 1.7,没装或只装了 1.8 的要去下一个 1.7 再装上。

mac_sdk_versions_supported 问题

我使用的系统版本为 EI Capitan,新于代码的配置文件,因此要修改配置文件。它位于 build/core/combo/mac_version.mk,其中有一个 mac_sdk_versions_supported 变量,修改为我目前的版本 10.11

源代码的编译

参考官方指南 Building the System 先用 build/envsetup.sh 设置环境变量,再调用 lunch 命令选择构建目标。之后即执行 make -jN 进行编译。我用的参数为 -j4 编译了大约两个小时:

Creating filesystem with parameters:
    Size: 1610612736
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8192
    Inode size: 256
    Journal blocks: 6144
    Label: system
    Blocks: 393216
    Block groups: 12
    Reserved block group size: 95
Created filesystem with 1452/98304 inodes and 101032/393216 blocks
Install system fs image: out/target/product/generic/system.img
out/target/product/generic/system.img+ maxsize=1644333504 blocksize=2112 total=1610612736 reserve=16610880

e[0;32m#### make completed successfully (01:56:47 (hh:mm:ss)) ####e[00m

将代码导入 Android Studio

代码目录中含有一个名为 idegen 的模块,它能够为 Android 代码生成 Android Studio 下的工程文件。

具体编译、使用方法可以参考这篇 使用Android Studio导入源码。大体过程是, idegen 是一个模块,要先使用 mmm 编译一下,之后在 idegen 的文件目录下有一个脚本,在代码根目录下执行这个脚本,它就会遍历代码目录生成工程文件,很方便。另外,这篇博客中还讲解了如何裁剪 android.iml,排除掉不需要加载到 Android Studio 到代码,有助于加快载入速度。

完成后,用 Android Studio 就像打开普通的工程一样,打开这个工程,经历一番加载与 indexingAndroid 的代码就导入进来了。最后附上一张截图:

1xxx.pic_hd

参考文献

在实践过程中,我还参考了一下文章。感谢这些兄弟分享的经验。

如何阅读 Android 系统源码-收藏必备

Android拓展系列(10)--使用Android Studio阅读整个Android源码

Mac 10.10 编译android 4.4.4 for nexus



  1. 1 warning generated.
    [ 4% 669/14452] Ensure Jack server is installed and started
    FAILED: /bin/bash -c "(true) && (prebuilts/sdk/tools/jack-admin install-server prebuilts/sdk/tools/jack-launcher.jar prebuilts/sdk/tools/jack-server-4.1.ALPHA.jar 2>&1 || (exit 0)) && (JACK_SERVER_VM_ARGUMENTS=\"-Dfile.encoding=UTF-8 -XX:+TieredCompilation\" prebuilts/sdk/tools/jack-admin start-server 2>&1 || exit 0) && (prebuilts/sdk/tools/jack-admin update server prebuilts/sdk/tools/jack-server-4.1.ALPHA.jar 4.1.ALPHA 2>&1 || exit 0) && (prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack--1.1.PRE_ALPHA.jar -1.1.PRE_ALPHA || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack--1.2.PRE_ALPHA.jar -1.2.PRE_ALPHA || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack--1.3.PRE_ALPHA.jar -1.3.PRE_ALPHA || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-2.26.RELEASE.jar 2.26.RELEASE || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-3.7.ALPHA.jar 3.7.ALPHA || exit 47; prebuilts/sdk/tools/jack-admin update jack prebuilts/sdk/tools/jacks/jack-3.8.ALPHA.jar 3.8.ALPHA || exit 47)"
    Unsupported curl, please use a curl not based on SecureTransport
    Launching Jack server java -Djava.io.tmpdir=/var/folders/6r/72rm98ss6h55ftgqht_xkb_m0000gn/T/ -Dfile.encoding=UTF-8 -XX:+TieredCompilation -cp /Users/zrck/.jack-server/launcher.jar com.android.jack.launcher.ServerLauncher
    prebuilts/sdk/tools/jack-admin: line 248: /Users/zrck/.jack-server/logs/outputs.txt: No such file or directory
    Jack server failed to (re)start, see Jack server log
    Unsupported curl, please use a curl not based on SecureTransport
    Unsupported curl, please use a curl not based on SecureTransport
    [ 4% 669/14452] target thumb C++: lib...xternal/v8/src/arm/full-codegen-arm.cc
    ninja: build stopped: subcommand failed.
    make: *** [ninja_wrapper] Error 1

    mac osx 10.10 platform_vesion 6.0.1 编译报错,能帮忙看下是什么问题吗 万分感谢!!!

    • 编译系统 Jack 没有起来,问题出在 Jack 启动时有一个更新,使用到了 curl。“Unsupported curl, please use a curl not based on SecureTransport”,貌似是你系统中的curl与Jack不兼容。

      • 非常感谢 我重新下载了macports 然后按照官方文档的步骤下载了必需包,里面就包含了curl的更新,会自动根据你的环境匹配对应的版本,问题解决。

  2. 大神,帮忙看看。我这个问题是什么???

    Check package name for out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/conscrypt_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/okhttp_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/core-junit_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/bouncycastle_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ext_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/telephony-common_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/voip-common_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/ims-common_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/apache-xml_intermediates/classes.jar out/target/common/obj/JAVA_LIBRARIES/org.apache.http.legacy.boot_intermediates/classes.jar
    target R.java/Manifest.java: BasicDreams (out/target/common/obj/APPS/BasicDreams_intermediates/src/R.stamp)
    Building with Jack: out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/with-local/classes.dex

    Launching background server java -Dfile.encoding=UTF-8 -Xms2560m -XX:+TieredCompilation -jar out/host/linux-x86/framework/jack-launcher.jar -cp out/host/linux-x86/framework/jack.jar com.android.jack.server.JackSimpleServer
    ERROR: Cannot launch Jack server
    make: *** [out/target/common/obj/JAVA_LIBRARIES/core-libart_intermediates/with-local/classes.dex] 错误 41
    good@ubuntu:~/Documents/android-6.0$

    • 你试试开启swap,给它4G左右,问题就应该解决了,你搜一下ubuntu下开启swap,你跟着做就可以,我的也是这个问题,我虚拟机给了6G内存也在这出差,开启是swap后就过了,是运存不够的问题