Android源码介绍编译

Android源码介绍编译

AOSP Android Open Source Project

Android是一种为各种不同外形设备而开发的开源软件栈。 Android的主要目的是为运营商,OEM和开发人员创建一个开放的软件平台,使他们的创新理念成为现实,并引入一个成功的现实世界产品,改善用户的移动体验。
Android开源代码软件栈

部分版本对应的分支以及支持的设备列表(详细):

BuildBranchVersionSupported devices
N2G47Oandroid-7.1.2_r8NougatNexus 5X, Nexus 6P, Pixel XL, Pixel, Pixel C
MRA58Kandroid-6.0.0_r1MarshmallowNexus 5, Nexus 6, Nexus 7 (flo/deb), Nexus 9 (volantis/volantisg), Nexus Player
LRX22Candroid-5.0.1_r1LollipopNexus 4, Nexus 5, Nexus 6 (shamu), Nexus 7 (flo), Nexus 9 (volantis/volantisg), Nexus 10
KTU84Qandroid-4.4.4_r2KitKatNexus 5 (hammerhead) (For 2Degrees/NZ, Telstra/AUS and India ONLY)
IMM76Landroid-4.0.4_r2.1Ice Cream Sandwich

Android开源项目的首选许可证是Apache软件许可证2.0版(“Apache 2.0”),大多数Android软件都使用Apache 2.0授权。 虽然该项目将努力遵守首选许可证,但可能会有例外情况将根据具体情况处理。 例如,Linux内核修补程序在GPLv2许可证下,系统异常,可以在kernel.org上找到。
常见许可证:
1. ASL Apache Software License Apache软件许可证
ASL是一种不设限的许可证,允许软件的商业性开发和垄断式发布。简单来说就是修改后可以不开源。
2. GPL General Public License 自由软件基金会通用开放许可证
GPL是一种CopyLeft许可证,规定所有对源码的修改和衍生都必须公开,并以类似的许可证发布。
3. BSD Berkly Software Distribution 与ASL类似,在修改源码可以不开源。

Android编译环境要求

硬件要求
  1. 编译2.3.x及以后的版本需要64位系统,之前的版本需要32位系统
  2. 检出代码需要100GB磁盘,单个系统构建需要150G磁盘空间,多个系统构建需要200GB及更多的空间。如果开启ccache,那就更多了
  3. 如果在虚拟机中运行Linux,则至少徐亚16GB的RAM交换
软件要求
操作系统

Android通常使用GNU / Linux或Mac OS操作系统构建。 也可以在不支持的系统(如Windows)上的虚拟机中构建Android。

  1. GUN/Linux

    • Android 6.0 (Marshmallow) - AOSP master: Ubuntu 14.04 (Trusty)
    • Android 2.3.x (Gingerbread) - Android 5.x (Lollipop): Ubuntu 12.04 (Precise)
    • Android 1.5 (Cupcake) - Android 2.2.x (Froyo): Ubuntu 10.04 (Lucid)
  2. Mac OS(Intel/x86)

    • Android 6.0 (Marshmallow) - AOSP master: Mac OS v10.10 (Yosemite) or later with Xcode 4.5.2 and Command Line Tools
    • Android 5.x (Lollipop): Mac OS v10.8 (Mountain Lion) with Xcode 4.5.2 and Command Line Tools
    • Android 4.1.x-4.3.x (Jelly Bean) - Android 4.4.x (KitKat): Mac OS v10.6 (Snow Leopard) or Mac OS X v10.7 (Lion) and Xcode 4.2 (Apple’s Developer Tools)
    • Android 1.5 (Cupcake) - Android 4.0.x (Ice Cream Sandwich): Mac OS v10.5 (Leopard) or Mac OS X v10.6 (Snow Leopard) and the Mac OS X v10.5 SDK
JDK

Ubuntu14.04之后的版本不再支持OpenJdk8,需要手动下载。
下面是编译各个Android系统版本所需对应的JDK版本。
* AOSP主分支:Ubuntu - OpenJDK 8, Mac OS - jdk 8u45 or newer
* Android 5.x(Lollipop) - Android 6.0(Marshmallow):Ubuntu-OpenJDK 7,Mac OS - jdk-7u71-macosx-x64.dmg
* Android 2.3.X(GingerBread) - Android 4.4.x(KitKat):Ubuntu - Java JDK 6, Mac OS - Java JDK 6
* Android 1.5 (Cupcake) - Android 2.2.x (Froyo): Ubuntu - Java JDK 5

关键包
  • Python 2.6 – 2.7 from python.org
  • GNU Make 3.81 – 3.82 from gnu.org(Android 3.2.x和更早的版本需要从3.82回退到旧版本,以避免构建错误)
  • Git 1.7 or newer from git-scm.com
设备二进制文件

创建构建环境

目前只支持Linux和Mac OS系统,不支持Windows系统。
在准备环境之前需要了解三个工具:Git,Repo,Gerrit。

  • Git
    开源的分布式版本控制系统,支持本地分支、提交、编辑、差异等。
  • Repo
    Repo是我们在Git之上构建的存储库管理工具。 Repo在必要时统一了许多Git存储库,上传到我们的版本控制系统,并自动部署了Android开发工作流程。 Repo并不意味着取代Git,只是为了在Android的上下文中更容易使用Git。 repo命令是可执行的Python脚本,您可以将其放在路径的任何位置。 在使用Android源文件时,您将使用Repo进行跨网络操作。 例如,使用单个Repo命令,您可以将文件从多个存储库下载到本地工作目录。
  • Gerrit
    Gerrit是使用git的项目的基于Web的代码审查系统。 Gerrit鼓励更多的集中使用Git,方法是允许所有授权用户提交更改,如果通过代码审查,这些更改将自动合并。 此外,Gerrit通过在浏览器中并排显示更改并启用内联注释来更轻松地进行审阅。

由于笔者使用的mac系统,所以只翻译Mac上的环境搭建,Linux系统可自行查看原文

MacOS环境搭建

在默认安装中,Mac OS运行在保护大小写但不区分大小写的文件系统上。 git不支持这种类型的文件系统,并会导致一些git命令(如git状态)异常地出现。 因此,我们建议您始终在区分大小写的文件系统上使用AOSP源文件。 这可以很容易地使用磁盘映像完成,如下所述。

一旦正确的文件系统可用,在现代Mac OS环境中构建主分支是非常简单的。 早期的分支机构需要一些额外的工具和SDK。

创建区分大小写的磁盘镜像

您可以使用磁盘映像在现有Mac OS环境中创建区分大小写的文件系统。 要创建映像,请启动磁盘工具并选择“新建映像”。 25GB的大小是完成构建的最小值; 更大的数字更加面向未来。 使用稀疏图像可以节省空间,同时允许随着需要而增长。 确保选择“区分大小写,记录日志”作为卷格式。

也可以通过shell使用一下命令来创建镜像:

# hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 40g ~/android.dmg

这将创建一个.dmg(或可能的.dmg.sparseimage)文件,一旦安装,它将作为一个驱动器,具有Android开发所需的格式。

如果需要变更镜像大小,可以使用以下命令:

# hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage

为了方便挂载和卸载android.dmg磁盘镜像,可以在~/.bash_profile文件中添加帮助函数。

  • 挂载镜像

    
    # mount the android file image
    
    function mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }
  • 卸载镜像

    
    # unmount the android file image
    
    function umountAndroid() { hdiutil detach /Volumes/android; }
安装JDK

编辑不同版本的Android源码需要不同版本的JDK,详情请查看“Android介绍及环境要求”

安装所需软件包
  1. 安装Xcode命令行工具

    $ xcode-select --install
  2. macports.org安装MacPorts

    export PATH=/opt/local/bin:$PATH

    注意:请确保在~/.bash_profile文件中,/opt/local/bin路径在 /usr/bin路径之前

  3. 通过MacPosts安装make,git和GPG

    $ POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg

    如果是Mac OS v10.4,还需要安装bison:

    $ POSIXLY_CORRECT=1 sudo port install biso
从make3.82退回

在Android4.0.x和更早版本,使用gmake3.82在构建Android源码时存在一个bug,需要使用MacPorts下载3.81版本。步骤如下:

  1. 编辑 /opt/local/etc/macports/sources.conf,添加如下内容

    file:///Users/Shared/dports

    然后创建对应目录:

    $ mkdir /Users/Shared/dports
  2. 在新的 dports 目录下,运行如下命令:

    $ svn co --revision 50980 http://svn.macports.org/repository/macports/trunk/dports/devel/gmake/ devel/gmake/
  3. 为新的本地仓库创建端口索引

    $ portindex /Users/Shared/dports
  4. 下载旧版的gmake

    $ sudo port install gmake @3.81
设置文件描述符限制

在Mac OS上,打开并行的文件描述符数量的默认限制太低,高度并行的构建过程可能会超出此限制。
为了提高这个限制,可以在~/.bash_profile文件中添加如下配置:

# set the number of open files to be 1024
ulimit -S -n 1024
优化构建环境
设置ccache

您可以选择告诉构建使用ccache编译工具,它是C和C ++的编译器缓存,可帮助构建更快。 它对于构建服务器和其他大批量生产环境特别有用。 Ccache作为可用于加速重建的编译器缓存。 如果您经常使用make clean,或者如果您经常在不同的构建产品之间切换,这样做效果非常好。

如果您改为执行增量版本(例如单个开发人员而不是构建服务器),则ccache可能会通过让您支付高速缓存未命中的费用来减慢您的构建速度。

要使用ccache,请在源代码树的根目录中发出这些命令。

$ export USE_CCACHE=1
$ export CCACHE_DIR=/<path_of_your_choice>/.ccache
$ prebuilts/misc/linux-x86/ccache/ccache -M 50G

建议缓存大小是50-100G
将以下内容放在.bashrc(或等效的文件)

export USE_CCACHE=1

默认情况下,缓存将存储在〜/ .ccache中。 如果您的主目录位于NFS或其他非本地文件系统上,那么您还需要在.bashrc文件中指定目录。
在Mac OS上,应当将linux-x86替换为darwin-x86:

prebuilts/misc/darwin-x86/ccache/ccache -M 50G

在构建4.0.x或更早的版本时,ccache处在不同的位置

prebuilt/linux-x86/ccache/ccache -M 50G

这些设置存在CCACHE_DIR中,并且是持久的。
在Linux上,可以使用以下命令观察ccache的使用情况:

$ watch -n1 -d prebuilts/misc/linux-x86/ccache/ccache -s

下载源码

下载Repo
确保在home目录下有bin/目录,并且已经添加到环境变量中。
$ mkdir ~/bin
$ PATH = ~/bin:$PATH
下载Repo工具,并确保可执行
$ curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
初始化Repo
创建存放工作文件的空目录。如果使用的是MacOS,这一步需要在大小写区分的文件系统中。向下面这样;
$ mkdir WORKING_DIRECTORY
$ cd WORKING_DIRRECTORY
配置真实的名称和邮件地址。为了使用Gerrit代码检查工具,需要设置一个邮件地址来连接一个已注册的Google账户。配置的名称则会展示在你的代码提交中。
$ git config --global user.name 'Your Name'
$ git config --global user.email 'you.@example.com'
执行 repo init 来下载Repo的最新版本。你必须指定manifest的URL,这个URL指定了Android源码中包含的各种仓库。
$ repo init -u https://android.googlesource.com/platform/manifest

如果想要检出非master分支,可以通过-b参数指定分支名称。具体分名称可见Source Code Tags and Builds

$ repo init -u https://android.googlesource.com/platform/manifest -b android-4.0.1_r1

初始化成功后,你的客户端目录会包含一个.repo目录,里面包含了manifest等文件。

下载Android源码树

拉取Android源码到工作目录。

repo sync

Android源码目录结构详解:

目录解释
abi应用二进制接口。不同的操作系统,应用二进制接口不同。因此linux上的二进制可执行文件在windows上无法执行。
artart虚拟机
bionicC库,Android没有使用标准的glibc库,而是自己实现的一套
bootable包含两个工程,recovery和bootloader。刷机或者系统升级都是由recovery完成的。
buildAndroid编译系统核心代码都存在该目录
ctsAndroid兼容性测试套件
dalvikdalvik虚拟机
developers
development开发相关的一些源码,如sdk、ndk工具
device硬件模块代码,不同设备,内容也不同
docs
external包含所有开源项目的源码,如sqlite、webkit、zxing等
frameworksAndroid框架源码。这里找到Android最核心的实现。
hardware硬件相关源码。如Android硬件抽象层的实现和规范,还包括所涉及的通信模块实现
libcore核心Java库,大部分取自于Apache Harmony的类库子集。(Apache Harmony虚拟机间接催生了Dalvik虚拟机)
libnativehelperJNI使用的帮助函数
Out运行make后生成的一些文件
ndk
packages包含系统默认应用的源码,如联系人、日历、浏览器等
pdk
prebuilts为方便提前编译好的二进制文件
sdk
systemAndroid系统核心的源码文件。这是在Dalvik虚拟机和所有java启动前所能运行的最小Linux系统。包含init进程、默认的init.rc脚本等
tools不同IDE工具
遇到的问题
repo init -u https://android.googlesource.com/a/platform/manifest
fatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundle
fatal: error [Errno 65] No route to host

使用proxyChains工具添加命令行翻墙功能后,访问超时

fatal: unable to access 'https://gerrit.googlesource.com/git-repo/': Failed to connect to gerrit.googlesource.com port 443: Operation timed out

折腾好久还是没有解决,只能用国内的镜像源替代了(清华大学开源软件镜像站)。
使用时将 https://android.googlesource.com/ 全部使用 https://aosp.tuna.tsinghua.edu.cn/ 代替即可

使用认证

默认情况下,访问Android源码是匿名的,为了保护服务器免受频繁的使用,每一个IP会有定额的访问限制。
当和他人使用共享IP时,尽管是正常使用,也会触发保护限制。
在这种情况下,应当使用认证访问方式。这种方式将限制策略由IP限制改成账户限制。
第一步,使用 the password generator来创建密码。
第二步,使用下面的manifest URI(https://android.googlesource.com/a/platform/manifest)进行强制认证访问。

$ repo init -u https://android.googlesource.com/a/platform/manifest
解决网络问题

当使用代理下载时,需要明确指定Repo使用的代理。一般在企业环境中比较常见

$ export HTTP_PROXY=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
$ export HTTPS_PROXY=http://<proxy_user_id>:<proxy_password>@<proxy_server>:<proxy_port>
$ unset HTTPS_PROXY  取消代理
使用本地镜像

当使用多个客户端时,特别是在带宽不足的情况下,最好创建整个服务器内容的本地镜像,并从该镜像(不需要网络访问)同步客户端。 整个镜像的下载小于下载两个客户端,同时包含更多的信息。
假设本地镜像目录为/usr/local/aosp/mirror。第一步就是创建并同步镜像本身。使用–mirror标识来创建新的客户端:

$ mkdir -p /usr/local/aosp/mirror
$ cd /usr/local/aosp/mirror
$ repo init -u https://android.googlesource.com/mirror/manifest --mirror
$ repo sync

一旦镜像同步完成后,就可以从中创建新的客户端。注意一定指定一个绝对路径:

$ mkdir -p /usr/local/aosp/master
$ cd /usr/local/aosp/master
$ repo init -u /usr/loca/aosp/mirror/platform/manifest.git
$ repo sync

最终,基于服务器同步镜像,其他的客户端基于镜像。

$ cd /usr/local/aosp/mirror
$ repo sync 
$ cd /usr/local/aosp/master
$ repo sync

可以将镜像存储在LAN服务器上,并通过NFS,SSH或Git进行访问。也可以将其存储在可移动驱动器上,并将该驱动器传递到用户之间或机器之间。

验证Git标签

加载下面公开的秘钥到你的GnuPG秘钥数据库中,秘钥用于签署代表版本的注释标签。

$ gpg --import

复制并粘贴下面的秘钥,然后输入EOF(Ctrl-D)来结束输入并处理秘钥。

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.4.2.2 (GNU/Linux)

mQGiBEnnWD4RBACt9/h4v9xnnGDou13y3dvOx6/t43LPPIxeJ8eX9WB+8LLuROSV
lFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw7
8tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMD
u4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0Z
wNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq
/HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5
jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4
MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9
b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJv
aWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5k
cm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIX
gAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI
2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAl
QN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806Up
hisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbk
C2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMX
LWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+
OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/M
pK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7s
KZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phb
N8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjA
vUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwo
G1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQ
hN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0l
EXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+jv2QSTlrx4KLM=
=Wi5D
-----END PGP PUBLIC KEY BLOCK-----

导入秘钥后,就可以使用下面命令验证任何标签了。

$ git tag -v TAG_NAME

准备构建

注:如果编译Android6.0和之后的版本,需要使用Jack工具,一种新的默认的工具链,后面会介绍。

获取专用的二进制文件

从AOSP上下载的源码不能单独编译,需要一些额外的硬件相关的专用库文件。例如硬件图形加速,详细请查看二进制硬件驱动文件地址Driver Binaries

下载

传送门

提取

每一组二进制文件作为压缩档案中的自解压脚本。 解压缩每个存档,从源代码树的根目录运行附带的自解压缩脚本,然后确认您同意附带的许可协议的条款。 二进制文件及其匹配的makefile将安装在源代码树的供应商/层次结构中。

清理

为了确保新安装的二进制文件被正确的提取,请使用以下命令删除任何以前版本的现有输出:

$ make clobber
设置环境

使用envsetup.sh脚本初始化环境。 请注意,用.(一个点)可以减少几个字符,简写在文档中更常用。

$ source build/envsetup.sh
or 
$ . build/envsetup.sh
选择构建类型

使用 lunch 命令选择构建类型,额外的配置可通过参数传递。例:

$ lunch aosp_arm-eng

若是为模拟器完整的构建,应启动所有调试。
如果不添加任何参数,lunch会通过菜单提示你来选择编译类型。
所有构建目标采用BUILD-BUILDTYPE形式,其中BUILD是引用特定功能组合的代号。BUILDTYPE是下面列表中的一个:

BuildtypeUse
user限制访问,适合生产部署
userdebug和user类似,但是拥有root权限和可调试的,适合调试部署
eng可使用额外的调试工具作为开发配置

更多关于构建和运行在实际硬件设备的信息,后面讲到。

编译代码

用make构建一切。 GNU make可以使用-jN参数来处理并行任务,并且通常使用一些任务N,该数目是用于构建的计算机上的硬件线程数的1到2倍。 例如,在双E5520机器(2个CPU,每个CPU 4个内核,每个核心2个线程)上,最快的版本是通过make -j16和make -j32之间的命令进行的。

$ make -j4
运行

您可以在仿真器上运行构建程序,也可以将其部署在真实设备上。 请注意,您已经使用lunch选择了您的构建目标,并且不太可能运行在与其构建的目标不同的目标上。

使用fastboot刷设备

要刷新设备,您将需要使用fastboot,该应用程序在成功构建后应包含在路径中。详情参考https://source.android.com/source/running.html#flashing-a-device

模拟Android设备

在构建过程中,模拟器已经自动添加到你的路径中了。执行下面的命令运行模拟器:

$ emulator
常见构建错误解决
错误的Java版本

在构建过程中使用不匹配的Java版本,make会终止并输出一下信息:

************************************************************
You are attempting to build with the incorrect version
of java.

Your version is: WRONG_VERSION.
The correct version is: RIGHT_VERSION.

Please follow the machine setup instructions at
    https://source.android.com/source/initializing.html
************************************************************

可能引起的原因:

  1. 没有按照要求下载正确的JDK版本。
  2. 在环境变量里有之前下载的JDK。
Python版本为3

Repo是基于Python2.x的特定功能构建,不与Python3兼容,为了使用repo,请安装Python2.x

$ apt-get install python
大小写敏感的文件系统

如果您基于Mac OS上的HFS文件系统构建,您可能会遇到诸如此类的错误

************************************************************
You are building on a case-insensitive filesystem.
Please move your source tree to a case-sensitive filesystem.
************************************************************

解决方法请查看创建构建系统部分

没有USB权限

在大多数Linux系统上,默认情况下,无特权用户无法访问USB端口。 如果您看到权限被拒绝的错误,请按照说明初始化构建环境以配置USB访问。

如果adb已经运行,并且在设置好这些规则后无法连接到设备,则可以使用adb kill-server进行杀死。 这将导致adb使用新配置重新启动。

使用Jack编译

根据本公告,Jack工具链已被弃用。 但是,您可以继续使用它来启用Java 8语言功能,直到发布可用的替代品。

Jack工具链

Jack是一个新的Android工具链,将Java源代码编译成Android dex字节码。 它替代了以前的Android工具链,它由多个工具组成,如javac,ProGuard,jarjar和dx。

Jack工具链具有以下优势:
* 完全开源
在AOSP上可用
* 加速编译
Jack使用特殊的支持来减少编译时间,包括预先dex转换、增量编译和Jack编译服务器
* 解决压缩、混淆、重新打包、多dex
不再使用单独的软件包,例如Proguard

从Android7.0(N)开始,Jack支持使用JaCoCo统计代码覆盖率。详情查看JaCoCo代码覆盖率Java8语言特性

Jack概览

Jack库文件格式

杰克有自己的.jack文件格式,其中包含预编译的dex代码库,允许更快的编译(pre-dex)。

Jack库文件内容

Jill

Jill工具将已有的.jar库转换成新的库文件格式。

转换已有的.jar库文件流程

在Android编译过程中使用Jack

使用Jack编译Android7.0及以后版本请移步Jack服务端文档

Jack是Android M上默认的编译工具链。你不需要做任何更改就可以使用标砖的makefile命令去编译源码树或你的工程。

第一使用Jack是,会在你的电脑上启动一个本地的Jack编译服务器。

  • 该服务器带来内在加速,因为它避免启动新的宿主JRE JVM,加载Jack代码,初始化Jack并在每次编译时加热JIT。 它也在小编译期间提供非常好的编译时间(例如在增量模式下)。
  • 该服务器也是一个短期解决方案,用于控制并行Jack编译的数量,因此避免计算机(内存或磁盘问题)过载,因为它限制了并行编译的数量。

Jack服务器在空闲时间后自动关闭,无需任何编译。 它在localhost接口上使用两个TCP端口,因此外部不可用。 可以通过编辑$ HOME / .jack文件修改所有这些参数(并行编译次数,超时时间,端口号等)。

$HOME/.jack file

$HOME/.jack文件包含了Jack服务端的变量设置,采用完整的bash语法。
下面是这些变量的设置,包含定义和默认值。

  • SERVER=true 启动Jack服务端特性
  • SERVER_PORT_SERVICE=8072 设置服务端编译的TCP端口号
  • SERVER_PORT_ADMIN=8073 设置服务端管理的TCP端口号
  • SERVER_COUNT=1 目前没有使用
  • SERVER_NB_COMPILE=4 允许的最大并行编译数量
  • SERVER_TIMEOUT=60 服务端在没有编译任务后,等待关闭自己的空闲时长。
  • SERVER_LOG={SERVER_LOG:=SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} 服务器日志文件所在目录。默认情况下,可以被环境变量覆盖。
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:java} 启动JVM的默认命令。默认情况下,可以被环境变量覆盖。
Jack问题解决
  1. 编译过程中电脑无响应或编译失败“Out of memory error”
    通过修改$HOME/.jack文件中的SERVER_NB_COMPILE值,来降低并行编译数量

  2. 编译失败“Cannot launch background server”
    首先可能是端口占用,修改SERVER_PORT_SERVICE和SERVER_PORT_ADMIN的值。

    如果不能解决问题,就只能关闭Jack编译服务(SERVER=false),并上报Jack日志。

  3. 如果编译没有任何进展就卡住了
    上报日志病提供额外的信息:

    • 卡在了哪一条命令
    • 命令行输出
    • jack-admin server-stat命令的输出
    • $HOME/.jack文件
    • 服务端状态转储的日志内容

      • 执行jack-admin list-server命令找出Jack后台服务进程
      • 发送kill -3命令来存储服务端状态到日志文件
      • 定位服务端日志文件,后面会说到
    • 执行 ls -lR TMPDIR/jack USER的结果

    • 执行 ps j -U $USER的结果

    你应该能够通过杀死Jack后台服务(jack-admin kill-server)来解除锁定,然后删除jack-$USER下的临时目录。

  4. 其他问题
    访问http://b.android.com来上报错误或请求新特性

    找到Jack日志文件

    • 如果是执行make命令, Jack日志文件位于$ANDROID_BUILD_TOP/out/dist/logs/jack-server.log
    • 否则的话可以通过执行jack-admin server-log 来找到它

为了可以复现Jack失败,你可以获取更详细的日志通过设置一个变量:

$ export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -Dsched.runner=single-threaded"

然后使用标准的makefile命令来编译源码树或工程,并附加其标准输出和错误。
使用以下命令移除详细的构建日志:

$ unset ANDROID_JACK_EXTRA_ARGS
Jack的限制
  • 默认情况下,Jack服务器是单用户的,因此只能由计算机上的一个用户使用。 如果不是这样,请为每个用户选择不同的端口号,并相应调整SERVER_NB_COMPILE。 您还可以通过在$ HOME / .jack中设置SERVER = false来禁用Jack服务器。

  • 由于目前的vm-tests-tf集成,CTS(兼容测试套件)编译速度很慢。

  • 不支持字节码操作工具如JaCoCo
使用Jack特性

Jack支持Java1.7和集成了额外的特性

预先Dex

第三方库文件是以class文件形式存在,Jack会将这些文件预先dex编译。
当生成Jack库文件时,会生成.dex文件并以pre-dex的形式存储在.jack库文件中。
当编译时,Jack会从每一个库文件中重用pre-dex。
所有的库文件都会被预先dex。

限制

目前,如果在编译过程中启用了混淆、重新打包、压缩资源,Jack不会重用pre-dex

启动增量编译

增量编译默认不会启动,如果想要增量构建,需要在工程下Android.mk文件中添加如下配置:

LOCAL_JACK_ENABLED := incremental

注:如果在第一次使用Jack构建时,缺少一些依赖。先使用mma构建他们,然后再使用标准的构建命令

资源压缩和混淆

Jack通过使用混淆配置文件来启动资源法索和混淆。下面是支持和忽略的选项:

支持的一般选项
  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars // only 1 output jar supported
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds
支持的资源压缩选项
  • -dontshrink
支持的混淆选项
  • -dontobfuscate
  • -printmapping
  • -applymapping
  • -obfuscationdictionary
  • -classobfuscationdictionary
  • -packageobfuscationdictionary
  • -useuniqueclassmembernames
  • -dontusemixedcaseclassnames
  • -keeppackagenames
  • -flattenpackagehierarchy
  • -repackageclasses
  • -keepattributes
  • -adaptclassstrings
忽略的选项
  • -dontoptimize // Jack does not optimize
  • -dontpreverify // Jack does not preverify
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump
重新打包

Jack使用jarjar配置文件做重新打包。

多dex支持

Jack提供原生的和遗留的多dex支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值