近日有幸加入魅族 Flyme 团队参与系统研发的工作,涉及到 Android Framework 层面的开发工作。在此之前都是基于应用层面的开发,于是开始编写 Android Framework 系列博客记录我从应用开发到系统开发的成长。

本文基于 Ubuntu 16.04 进行编译,若无 Ubuntu 系统建议使用 Docker 挂载进行编译,Android 亦提供了 Mac 下的编译方式,具体可参考设置 macOS 编译环境。这篇文章将介绍如何下载、编译 AOSP 源码并将其导入 Android Studio。

1、安装 OpenJDK8

AOSP 要求在 Ubuntu 上使用 OpenJDK:

sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jdk
sudo update-alternatives --config java
sudo update-alternatives --config javac

完成后通过 java -version 查看 JDK 版本。

2、安装编译环境所需软件

sudo 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 libssl-dev

3、Git/Repo 安装

Git 安装

apt-get install git

Repo 安装

确保主目录中有一个 bin/ 目录,并且它包含在该路径中:

mkdir ~/bin
PATH=~/bin:$PATH

下载 Repo 工具,并确保它可执行:

curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

4、源码下载

进入版本分支列表:https://source.android.com/setup/start/build-numbers#source-code-tags-and-builds

选择需要下载的机型源码。以 android-9.0.0_r45 为例:

repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r45 --depth=1

--depth=1 为浅拷贝, -b 选择指定分支,可节省空间、时间,如果恰巧你资力雄厚网速够快机器硬盘够大当然可以直接全量下载:

repo init -u https://android.googlesource.com/platform/manifest

init 成功后通过 repo sync -c 加载代码,-c 表示加载当前分支,若不加此参数会加载其他分支的代码信息,耗时较长。当然如果恰巧你资力雄厚机器够牛逼,那么把 -c 去掉即可全量获取。

5、源码编译

在源代码根目录下使用命令 source build/envsetup.sh 运行该脚本将 envsetup.sh 里的函数声明为当前会话终端可用的命令,完毕后通过 lunch 命令选择需要编译的项目,可在 FVCS 中查看。选择完毕后即可开始源码编译。

在编译过程中,遇到过 Jack OOM 的错误,故在编译之前,先将 Jack 的内存设大:

export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m"
out/host/linux-x86/bin/jack-admin kill-server
out/host/linux-x86/bin/jack-admin start-server

全部编译:先通过命令 make update-api -j8 更新 apk-api.txt 文件,然后使用 make -j8 编译。后面的 -j8 表示启用多少线程,一般为 CPU 核心数的一到二倍,比如电脑核心数为 8 核,则可在 -j8 到 -j16 间按需选择。

模块编译:例如编译 SystemUI 可以在源码根目录下使用 mmm frameworks/base/packages/Keyguard/ && mmm frameworks/base/packages/SystemUI/

6、代码导入 Android Studio

编译完成后,在源码根目录执行命令 mmm development/tools/idegen/ 或者 make idegen 编译 idegen.jar 包,然后执行 ./development/tools/idegen/idegen.sh ,在根目录下生成了 android.ipr 及 android.iml,在 Android Studio 中打开 android.ipr 即可将源码导入。

注:导入所有源码模块会很慢,可在 android.iml 中用 excludeFolder 将一些不关心的模块过滤掉,仅保留 package 模块和 framework 模块。

      <excludeFolder url="file://$MODULE_DIR$/.repo" />
      <excludeFolder url="file://$MODULE_DIR$/art" />
      <excludeFolder url="file://$MODULE_DIR$/bionic" />
      <excludeFolder url="file://$MODULE_DIR$/bootable" />
      <excludeFolder url="file://$MODULE_DIR$/build" />
      <excludeFolder url="file://$MODULE_DIR$/commontools" />
      <excludeFolder url="file://$MODULE_DIR$/compatibility" />
      <excludeFolder url="file://$MODULE_DIR$/cts" />
      <excludeFolder url="file://$MODULE_DIR$/dalvik" />
      <excludeFolder url="file://$MODULE_DIR$/developers" />
      <excludeFolder url="file://$MODULE_DIR$/development" />
      <excludeFolder url="file://$MODULE_DIR$/device" />
      <excludeFolder url="file://$MODULE_DIR$/disregard" />
      <excludeFolder url="file://$MODULE_DIR$/external" />
      <excludeFolder url="file://$MODULE_DIR$/external/bluetooth" />
      <excludeFolder url="file://$MODULE_DIR$/external/chromium" />
      <excludeFolder url="file://$MODULE_DIR$/external/emma" />
      <excludeFolder url="file://$MODULE_DIR$/external/icu4c" />
      <excludeFolder url="file://$MODULE_DIR$/external/jdiff" />
      <excludeFolder url="file://$MODULE_DIR$/external/webkit" />
      <excludeFolder url="file://$MODULE_DIR$/frameworks/base/docs" />
      <excludeFolder url="file://$MODULE_DIR$/hardware" />
      <excludeFolder url="file://$MODULE_DIR$/kernel" />
      <excludeFolder url="file://$MODULE_DIR$/libcore" />
      <excludeFolder url="file://$MODULE_DIR$/libnativehelper" />
      <excludeFolder url="file://$MODULE_DIR$/out" />
      <excludeFolder url="file://$MODULE_DIR$/out/eclipse" />
      <excludeFolder url="file://$MODULE_DIR$/out/host" />
      <excludeFolder url="file://$MODULE_DIR$/out/target/common/docs" />
      <excludeFolder url="file://$MODULE_DIR$/out/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates" />
      <excludeFolder url="file://$MODULE_DIR$/out/target/product" />
      <excludeFolder url="file://$MODULE_DIR$/pdk" />
      <excludeFolder url="file://$MODULE_DIR$/platform_testing" />
      <excludeFolder url="file://$MODULE_DIR$/prebuilt" />
      <excludeFolder url="file://$MODULE_DIR$/prebuilts" />
      <excludeFolder url="file://$MODULE_DIR$/sdk" />
      <excludeFolder url="file://$MODULE_DIR$/shortcut-fe" />
      <excludeFolder url="file://$MODULE_DIR$/system" />
      <excludeFolder url="file://$MODULE_DIR$/test" />
      <excludeFolder url="file://$MODULE_DIR$/toolchain" />
      <excludeFolder url="file://$MODULE_DIR$/tools" />
      <excludeFolder url="file://$MODULE_DIR$/vendor" />
      <excludeFolder url="file://$MODULE_DIR$/wingcust" />

至此, AOSP 源码就编译好并导入到 Android Studio 了。后面的文章将会围绕 SystemUI 进行介绍,并刷入真机/虚拟机中进行调试,希望能记录下自己在另一个方向的成长,欢迎与我交流:me@york1996.com。

标签: Android

添加新评论