Android 6.0~8.1용 Jack으로 컴파일하기

Jack은 자바 소스를 Android DEX 바이트 코드로 컴파일한 Android 도구 모음입니다. Jack을 사용하기 위해 다른 방식으로 작업을 할 필요가 없습니다. 표준 makefile 명령어를 사용하여 트리나 프로젝트를 컴파일하면 됩니다. Android 8.1은 Jack을 사용하는 마지막 버전입니다.

Jack 정보

Jack은 그림 1과 같이 작동합니다.

Jack 개요
그림 1. Jack 개요

Jack 라이브러리 형식

Jack은 라이브러리에 관해 사전 컴파일된 dex 코드를 포함하는 자체 .jack 파일 형식을 가지고 있으므로 컴파일(pre-dex)이 더 빠릅니다.

Jack 라이브러리 파일 콘텐츠
그림 2. Jack 라이브러리 파일 콘텐츠

Jill

Jill 도구는 아래 그림과 같이 기존의 .jar 라이브러리를 새 라이브러리 형식으로 변환합니다.

Jill을 사용하여 .jar 라이브러리 가져오기
그림 3. 기존 .jar 라이브러리를 가져오는 워크플로

Jack 컴파일 서버

Jack을 처음 사용하면 컴퓨터에 로컬 Jack 컴파일 서버가 실행됩니다. 이 서버는 다음 역할을 합니다.

  • 새로운 호스트 JRE JVM의 시작, Jack 코드 로드, Jack 초기화 및 각 컴파일시 JIT 예열을 피하기 때문에 본질적으로 속도가 향상됩니다. 또한 소규모 컴파일 중(예: 증분 모드)에 매우 우수한 컴파일 시간을 제공합니다.
  • 병렬 Jack 컴파일 수를 제어하는 단기 솔루션입니다. 서버는 병렬 컴파일 수를 제한하므로 컴퓨터 오버로드(메모리 또는 디스크 문제)를 피합니다.

Jack 서버는 컴파일 없이 유휴 시간이 지나면 자동으로 종료됩니다. localhost 인터페이스에서 TCP 포트 2개를 사용하며 외부에서 사용할 수 없습니다. 모든 매개변수(병렬 컴파일 수, 시간 제한, 포트 번호 등)는 $HOME/.jack 파일 수정을 통해 수정될 수 있습니다.

$HOME/.jack 파일

$HOME/.jack 파일에는 전체 bash 구문으로 Jack 서버 변수의 다음 설정이 포함되어 있습니다.

  • 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 컴파일 문제해결

문제 작업
컴파일하는 동안 컴퓨터가 응답하지 않거나 메모리 부족 오류로 인해 Jack 컴파일이 실패함 $HOME/.jack을 수정하고 SERVER_NB_COMPILE을 더 낮은 값으로 변경하여 Jack 동시 컴파일 수를 줄임
백그라운드 서버를 실행할 수 없음에서 컴파일이 실패함 TCP 포트가 이미 컴퓨터에서 사용 중이기 때문일 수 있음. $HOME/.jack을 수정하여 포트를 변경(SERVER_PORT_SERVICESERVER_PORT_ADMIN 변수)함. 차단을 해제하려면 $HOME/.jack을 수정하고 SERVERfalse로 변경하여 Jack 컴파일 서버를 사용 중지함. 그러나 이렇게 하면 컴파일 속도가 크게 느려지고 로드 제어(make의 옵션 -l)와 함께 make -j를 실행해야 할 수 있음
컴파일이 진행되지 않고 멈춤 차단을 해제하려면 jack-admin kill-server를 사용하여 Jack 백그라운드 서버를 종료한 다음 임시 디렉터리(/tmp 또는 $TMPDIR)의 jack-$USER에 포함된 임시 디렉터리를 삭제합니다.

Jack 로그 찾기

dist 타겟과 함께 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 -D sched.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은 자바 프로그래밍 언어 1.7을 지원하며 아래에 설명된 추가 기능을 통합합니다.

사전 덱싱

Jack 라이브러리 파일을 생성할 때 라이브러리의 .dex가 생성되고 pre-dex로 .jack 라이브러리 파일 내부에 저장됩니다. 컴파일할 때 Jack은 각 라이브러리에서 pre-dex를 재사용합니다. 모든 라이브러리는 사전 덱싱되어 있습니다.

pre-dex가 포함된 Jack 라이브러리
그림 4. pre-dex가 포함된 Jack 라이브러리

컴파일에서 축소, 난독화 또는 재구성이 사용되는 경우 Jack은 라이브러리 pre-dex를 재사용하지 않습니다.

증분 컴파일

증분 컴파일은 마지막 컴파일 이후 변경된 구성요소와 종속 항목만 다시 컴파일됨을 의미합니다. 변경사항이 구성요소 모음으로 제한되는 경우 증분 컴파일이 전체 컴파일보다 훨씬 빠를 수 있습니다.

증분 컴파일은 기본적으로 사용 중지되어 있으며 축소, 난독화, 재구성, 멀티덱스 레거시가 사용 설정되면 자동으로 사용 중지됩니다. 증분 빌드를 사용하려면 증분식으로 빌드할 프로젝트의 Android.mk 파일에 다음 행을 추가합니다.

LOCAL_JACK_ENABLED := incremental

축소 및 난독화

Jack은 ProGuard 구성 파일을 사용하여 축소및 난독화를 사용 설정합니다.

일반적인 옵션에는 다음이 포함됩니다.

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars(출력 Jar 1개만 지원됨)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

축소 옵션에는 다음이 포함됩니다.

  • -dontshrink

난독화 옵션에는 다음이 포함됩니다.

  • -dontobfuscate
  • -printmapping
  • -applymapping
  • -obfuscationdictionary
  • -classobfuscationdictionary
  • -packageobfuscationdictionary
  • -useuniqueclassmembernames
  • -dontusemixedcaseclassnames
  • -keeppackagenames
  • -flattenpackagehierarchy
  • -repackageclasses
  • -keepattributes
  • -adaptclassstrings

무시되는 옵션에는 다음이 포함됩니다.

  • -dontoptimize(Jack이 최적화하지 않음)
  • -dontpreverify(Jack이 사전 확인하지 않음)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

재구성

Jack은 jarjar 구성 파일을 사용하여 재구성합니다. Jack은 'rule' 규칙 유형과 호환되지만 'zap' 또는 'keep' 규칙 유형과는 호환되지 않습니다.

멀티덱스 지원

Jack은 네이티브 및 기존 멀티덱스 지원을 제공합니다. dex 파일은 65K 메서드로 제한되므로 65K 메서드를 넘는 앱은 여러 dex 파일로 분할되어야 합니다. 자세한 내용은 64K가 넘는 메서드가 있는 앱에 multidex 사용 설정을 참조하세요.