Android源码介绍编译

来源:互联网 发布:达示数据 编辑:程序博客网 时间:2024/04/27 22:22

Android源码介绍编译

AOSP Android Open Source Project

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

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

Build Branch Version Supported devices N2G47O android-7.1.2_r8 Nougat Nexus 5X, Nexus 6P, Pixel XL, Pixel, Pixel C MRA58K android-6.0.0_r1 Marshmallow Nexus 5, Nexus 6, Nexus 7 (flo/deb), Nexus 9 (volantis/volantisg), Nexus Player LRX22C android-5.0.1_r1 Lollipop Nexus 4, Nexus 5, Nexus 6 (shamu), Nexus 7 (flo), Nexus 9 (volantis/volantisg), Nexus 10 KTU84Q android-4.4.4_r2 KitKat Nexus 5 (hammerhead) (For 2Degrees/NZ, Telstra/AUS and India ONLY) IMM76L android-4.0.4_r2.1 Ice 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
设备二进制文件
  • 工厂二进制镜像文件地址Factory Images
  • OTA二进制镜像文件地址Full OTA Images
  • 二进制硬件驱动文件地址Driver Binaries
  • 支持Nexus设备的二进制预览文件Preview binaries(blobs)

创建构建环境

目前只支持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 imagefunction mountAndroid { hdiutil attach ~/android.dmg -mountpoint /Volumes/android; }
  • 卸载镜像

    # unmount the android file imagefunction 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 1024ulimit -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上无法执行。 art art虚拟机 bionic C库,Android没有使用标准的glibc库,而是自己实现的一套 bootable 包含两个工程,recovery和bootloader。刷机或者系统升级都是由recovery完成的。 build Android编译系统核心代码都存在该目录 cts Android兼容性测试套件 dalvik dalvik虚拟机 developers development 开发相关的一些源码,如sdk、ndk工具 device 硬件模块代码,不同设备,内容也不同 docs external 包含所有开源项目的源码,如sqlite、webkit、zxing等 frameworks Android框架源码。这里找到Android最核心的实现。 hardware 硬件相关源码。如Android硬件抽象层的实现和规范,还包括所涉及的通信模块实现 libcore 核心Java库,大部分取自于Apache Harmony的类库子集。(Apache Harmony虚拟机间接催生了Dalvik虚拟机) libnativehelper JNI使用的帮助函数 Out 运行make后生成的一些文件 ndk packages 包含系统默认应用的源码,如联系人、日历、浏览器等 pdk prebuilts 为方便提前编译好的二进制文件 sdk system Android系统核心的源码文件。这是在Dalvik虚拟机和所有java启动前所能运行的最小Linux系统。包含init进程、默认的init.rc脚本等 tools 不同IDE工具
遇到的问题
repo init -u https://android.googlesource.com/a/platform/manifestfatal: Cannot get https://gerrit.googlesource.com/git-repo/clone.bundlefatal: 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+8LLuROSVlFhpHawsVAcFlmi7f7jdSRF+OvtZL9ShPKdLfwBJMNkU66/TZmPewS4m782ndtw78tR1cXb197Ob8kOfQB3A9yk2XZ4ei4ZC3i6wVdqHLRxABdncwu5hOF9KXwCgkxMDu4PVgChaAJzTYJ1EG+UYBIUEAJmfearb0qRAN7dEoff0FeXsEaUA6U90sEoVks0ZwNj96SA8BL+a1OoEUUfpMhiHyLuQSftxisJxTh+2QclzDviDyaTrkANjdYY7p2cq/HMdOY7LJlHaqtXmZxXjjtw5Uc2QG8UY8aziU3IE9nTjSwCXeJnuyvoizl9/I1S5jU5SA/9WwIps4SC84ielIXiGWEqq6i6/sk4I9q1YemZF2XVVKnmI1F4iCMtNKsR4MGSa1gA8s4iQbsKNWPgp7M3a51JCVCu6l/8zTpA+uUGapw4tWCp4o0dpIvDPBEa9b/aF/ygcR8mh5hgUfpF9IpXdknOsbKCvM9lSSfRciETykZc4wrRCVGhlIEFuZHJvaWQgT3BlbiBTb3VyY2UgUHJvamVjdCA8aW5pdGlhbC1jb250cmlidXRpb25AYW5kcm9pZC5jb20+iGAEExECACAFAknnWD4CGwMGCwkIBwMCBBUCCAMEFgIDAQIeAQIXgAAKCRDorT+BmrEOeNr+AJ42Xy6tEW7r3KzrJxnRX8mij9z8tgCdFfQYiHpYngkI2t09Ed+9Bm4gmEO5Ag0ESedYRBAIAKVW1JcMBWvV/0Bo9WiByJ9WJ5swMN36/vAlQN4mWRhfzDOk/Rosdb0csAO/l8Kz0gKQPOfObtyYjvI8JMC3rmi+LIvSUT9806UphisyEmmHv6U8gUb/xHLIanXGxwhYzjgeuAXVCsv+EvoPIHbY4L/KvP5x+oCJIDbkC2b1TvVk9PryzmE4BPIQL/NtgR1oLWm/uWR9zRUFtBnE411aMAN3qnAHBBMZzKMXLWBGWE0znfRrnczI5p49i2YZJAjyX1P2WzmScK49CV82dzLo71MnrF6fj+Udtb5+OgTg7Cow+8PRaTkJEW5Y2JIZpnRUq0CYxAmHYX79EMKHDSThf/8AAwUIAJPWsB/MpK+KMs/s3r6nJrnYLTfdZhtmQXimpoDMJg1zxmL8UfNUKiQZ6esoAWtDgpqt7Y7sKZ8laHRARonte394hidZzM5nb6hQvpPjt2OlPRsyqVxw4c/KsjADtAuKW9/d8phbN8bTyOJo856qg4oOEzKG9eeF7oaZTYBy33BTL0408sEBxiMior6b8LrZrAhkqDjAvUXRwm/fFKgpsOysxC6xi553CxBUCH2omNV6Ka1LNMwzSp9ILz8jEGqmUtkBszwoG1S8fXgE0Lq3cdDM/GJ4QXP/p6LiwNF99faDMTV3+2SAOGvytOX6KjKVzKOSsfJQhN0DlsIw8hqJc0WISQQYEQIACQUCSedYRAIbDAAKCRDorT+BmrEOeCUOAJ9qmR0lEXzeoxcdoafxqf6gZlJZlACgkWF7wi2YLW3Oa+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.shor $ . build/envsetup.sh

选择构建类型

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

$ lunch aosp_arm-eng

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

Buildtype Use 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 versionof 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/jackUSER的结果

    • 执行 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支持。

0 0