编译Android时禁用Jack

本文的代码与方法,基于Android O(8.0)。

问题

根据Android官网的介绍《使用 Jack 编译》,似乎Jack工具链是不错的东西。

Jack 是一种新型 Android 工具链,用于将 Java 源代码编译成 Android dex 字节码。 它取代了之前由 javac、ProGuard、jarjar 和 dx 等多种工具组成的 Android 工具链。

Jack 工具链具有以下优势:

  • 完全开放源代码 它是在 AOSP 中提供的;并且欢迎用户贡献资源。
  • 提高编译速度 Jack 提供以下具体支持来减少编译时间:dex 预处理、增量编译和 Jack 编译服务器。
  • 支持压缩、混淆、重新打包和多 dex 处理 不再需要使用单独的软件包(如 ProGuard)

然而它也同时表明,Jack 工具链已被弃用

实际情况是,在单次编译中,Jack的优势很难体现。 而且,如果不手动停止Jack Server,它还会在后台一直运行,占用内存不放。

此外,对一些额外工具链的支持也较差,如静态代码分析。

禁用

在AOSP的master分支,以及Android O及以后版本,Android提供了禁用的支持。

在编译项目时,传入一个变量,即可实现禁用。

make 'ANDROID_COMPILE_WITH_JACK:=false'

原理

Android的全局编译工具与配置,都在项目根目录的build子目录下。

在其中,可以发现LOCAL_JACK_ENABLED,是决定一个模块是否使用Jack的关键。

而在build/make/core/clear_vars.mk可以发现, 这个值的全局默认值是DEFAULT_JACK_ENABLED

build/make/core/config.mk中,可以发现一个开关。

ifeq ($(ANDROID_COMPILE_WITH_JACK),true)
DEFAULT_JACK_ENABLED:=full
else
DEFAULT_JACK_ENABLED:=
endif

而最终,开关是在build/make/combo/javac.mk初始化。

ifndef ANDROID_COMPILE_WITH_JACK
# Defines if compilation with jack is enabled by default.
ANDROID_COMPILE_WITH_JACK := true
endif

所以,只需要在执行make时,初始化ANDROID_COMPILE_WITH_JACKfalse,即可实现全局禁用。

参考

另外,关于Jack Server的禁用,详见《编译Android时禁用Jack Server》。


相关笔记