Biên dịch với Jack (AOSP 6.0 – 8.1)

Jack là chuỗi công cụ bản dựng Android mặc định cho Android 6.0 – 8.1

Jack là một chuỗi công cụ Android đã biên dịch nguồn Java thành mã byte dex của Android. Bạn không cần làm gì khác để sử dụng Jack – chỉ cần dùng các lệnh makefile tiêu chuẩn để biên dịch cây hoặc dự án của bạn. Android 8.1 là bản phát hành cuối cùng sử dụng Jack.

Giới thiệu về Jack

Giắc cắm hoạt động như minh hoạ trong Hình 1.

Tổng quan về giắc cắm.

Hình 1. Tổng quan về giắc cắm.

Định dạng thư viện Jack

Jack có định dạng tệp .jack riêng chứa mã dex được biên dịch trước cho thư viện, cho phép biên dịch nhanh hơn (pre-dex).

Nội dung tệp thư viện Jack.

Hình 2. Nội dung tệp thư viện Jack.

Jill

Như minh hoạ trong hình sau, công cụ Jill sẽ dịch các thư viện .jar hiện có sang định dạng thư viện mới.

Quy trình nhập một thư viện `jar.` hiện có.

Hình 3. Quy trình nhập một thư viện .jar hiện có.

Máy chủ biên dịch Jack

Lần đầu tiên bạn sử dụng Jack, Jack sẽ khởi chạy một máy chủ biên dịch Jack cục bộ trên máy tính của bạn. Máy chủ này:

  • Mang lại tốc độ tăng tốc vốn có vì tránh khởi chạy một JVM JRE máy chủ mới, tải mã Jack, khởi tạo Jack và khởi động JIT ở mỗi lần biên dịch. Công cụ này cũng cung cấp thời gian biên dịch rất tốt trong quá trình biên dịch nhỏ (ví dụ: ở chế độ gia tăng).
  • Là một giải pháp ngắn hạn để kiểm soát số lượng các bản biên dịch Jack song song. Máy chủ tránh làm quá tải máy tính của bạn (vấn đề về bộ nhớ hoặc ổ đĩa) vì máy chủ giới hạn số lượng quá trình biên dịch song song.

Máy chủ Jack sẽ tự tắt sau một khoảng thời gian không hoạt động mà không có bất kỳ quá trình biên dịch nào. Công cụ này sử dụng 2 cổng TCP trên giao diện máy chủ cục bộ và không có sẵn bên ngoài. Bạn có thể sửa đổi tất cả các tham số (số lượng bản biên dịch song song, thời gian chờ, số cổng, v.v.) bằng cách chỉnh sửa tệp $HOME/.jack.

Tệp $HOME/.jack

Tệp $HOME/.jack chứa các chế độ cài đặt sau cho các biến máy chủ Jack theo cú pháp bash đầy đủ:

  • SERVER=true cho phép tính năng máy chủ của Jack.
  • SERVER_PORT_SERVICE=8072 đặt số cổng TCP của máy chủ cho mục đích biên dịch.
  • SERVER_PORT_ADMIN=8073 đặt số cổng TCP của máy chủ cho mục đích quản trị.
  • SERVER_COUNT=1 không được dùng.
  • SERVER_NB_COMPILE=4 đặt số lượng tối đa các lần biên dịch song song được phép. SERVER_TIMEOUT=60 đặt số giây không hoạt động mà máy chủ phải đợi mà không cần biên dịch trước khi tự tắt. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} đặt tệp nơi nhật ký máy chủ được ghi. Theo mặc định, biến này có thể bị quá tải bởi một biến môi trường.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} đặt lệnh mặc định dùng để chạy JVM trên máy chủ. Theo mặc định, biến này có thể bị quá tải do biến môi trường.

Khắc phục sự cố về tuyển tập Jack

Sự cố Thao tác
Máy tính của bạn không phản hồi trong quá trình biên dịch hoặc bạn gặp phải lỗi biên dịch Jack do Hết bộ nhớ Giảm số lượng các lần biên dịch Jack đồng thời bằng cách chỉnh sửa $HOME/.jack và thay đổi SERVER_NB_COMPILE thành một giá trị thấp hơn.
Quá trình biên dịch không thành công trên Không thể chạy máy chủ nền Nguyên nhân có thể nhất là các cổng TCP đã được sử dụng trên máy tính của bạn. Thay đổi cổng bằng cách chỉnh sửa $HOME/.jack (các biến SERVER_PORT_SERVICESERVER_PORT_ADMIN). Để giải quyết tình huống này, hãy tắt máy chủ biên dịch Jack bằng cách chỉnh sửa $HOME/.jack và thay đổi SERVER thành false. Rất tiếc, điều này làm chậm đáng kể quá trình biên dịch của bạn và có thể buộc bạn phải chạy make -j bằng tính năng kiểm soát tải (tuỳ chọn -l của make).
Quá trình biên dịch bị kẹt mà không có tiến trình nào Để khắc phục tình trạng này, hãy tắt máy chủ nền Jack bằng cách sử dụng jack-admin kill-server, sau đó xoá các thư mục tạm thời có trong jack-$USER của thư mục tạm thời (/tmp hoặc $TMPDIR).

Tìm nhật ký Jack

Nếu bạn chạy lệnh make với mục tiêu dist, thì nhật ký Jack sẽ nằm ở $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. Nếu không, bạn có thể tìm nhật ký bằng cách chạy jack-admin server-log. Trong trường hợp lỗi Jack có thể tái hiện, bạn có thể nhận được nhật ký chi tiết hơn bằng cách thiết lập biến sau:

export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"

Sử dụng các lệnh makefile tiêu chuẩn để biên dịch cây (hoặc dự án của bạn) và đính kèm đầu ra và lỗi tiêu chuẩn. Để xoá nhật ký chi tiết về bản dựng, hãy chạy:

unset ANDROID_JACK_EXTRA_ARGS

Giới hạn của giắc cắm

Theo mặc định, chỉ một người dùng trên máy tính có thể sử dụng máy chủ Jack. Để hỗ trợ thêm người dùng, hãy chọn số cổng khác nhau cho mỗi người dùng và điều chỉnh SERVER_NB_COMPILE cho phù hợp. Bạn cũng có thể tắt máy chủ Jack bằng cách đặt SERVER=false trong $HOME/.jack. Quá trình biên dịch CTS diễn ra chậm do chế độ tích hợp vm-tests-tf hiện tại. Các công cụ thao tác mã byte (chẳng hạn như JaCoCo) không được hỗ trợ.

Dùng Jack

Jack hỗ trợ ngôn ngữ lập trình Java 1.7 và tích hợp các tính năng bổ sung được mô tả dưới đây.

Pre-dex

Khi tạo tệp thư viện Jack, .dex của thư viện sẽ được tạo và lưu trữ bên trong tệp thư viện .jack dưới dạng một tệp dex trước. Khi biên dịch, Jack sẽ dùng lại tệp dex trước từ mỗi thư viện. Tất cả các thư viện đều được dex trước.

Thư viện Jack có tệp dex trước.

Hình 4. Thư viện Jack có tệp dex trước.

Jack không dùng lại thư viện pre-dex nếu quá trình biên dịch sử dụng tính năng thu nhỏ, làm rối mã nguồn hoặc đóng gói lại.

Biên dịch gia tăng

Biên dịch gia tăng có nghĩa là chỉ những thành phần được sửa đổi kể từ lần biên dịch gần đây nhất (và các phần phụ thuộc của chúng) mới được biên dịch lại. Việc biên dịch gia tăng có thể nhanh hơn đáng kể so với việc biên dịch đầy đủ khi các thay đổi chỉ giới hạn ở một nhóm thành phần.

Quá trình biên dịch gia tăng bị tắt theo mặc định (và tự động bị huỷ kích hoạt khi bật tính năng giảm kích thước, làm rối mã nguồn, đóng gói lại hoặc multi-dex cũ). Để bật bản dựng gia tăng, hãy thêm dòng sau vào tệp Android.mk của dự án mà bạn muốn tạo gia tăng:

LOCAL_JACK_ENABLED := incremental

Rút gọn và làm rối mã nguồn

Jack dùng các tệp cấu hình ProGuard để bật tính năng rút gọn và làm rối mã nguồn.

Các lựa chọn phổ biến bao gồm:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (chỉ hỗ trợ 1 tệp jar đầu ra)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

Có các lựa chọn thu nhỏ sau:

  • -dontshrink

Các lựa chọn làm rối mã nguồn bao gồm:

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

Các lựa chọn bị bỏ qua bao gồm:

  • -dontoptimize (Jack không tối ưu hoá)
  • -dontpreverify (Jack không xác minh trước)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Đóng gói lại

Jack sử dụng tệp cấu hình jarjar để đóng gói lại. Mặc dù Jack tương thích với các loại quy tắc "rule" (quy tắc), nhưng không tương thích với các loại quy tắc "zap" (xoá) hoặc "keep" (giữ lại).

Hỗ trợ multidex

Jack cung cấp tính năng hỗ trợ multidex cũ và tích hợp. Vì tệp dex bị giới hạn ở 65K phương thức, nên các ứng dụng có hơn 65K phương thức phải được chia thành nhiều tệp dex. Để biết thêm thông tin, hãy tham khảo bài viết Bật multidex cho các ứng dụng có hơn 64K phương thức