הידור עם Jack (AOSP 6.0 עד 8.1)

Jack הוא כלי ברירת המחדל ליצירת גרסת build של Android לגרסאות Android 6.0 עד 8.1

Jack הוא כלי עיבוד קוד ל-Android שמדרג קוד מקור של Java לקוד בינארי של Android dex. כדי להשתמש ב-Jack, אין צורך לעשות שום דבר אחר – פשוט משתמשים בפקודות הסטנדרטיות של קובץ ה-makefile כדי לקמפל את העץ או את הפרויקט. Android 8.1 היא הגרסה האחרונה שמשתמשת ב-Jack.

מידע על ג'ק

הלחצן פועל כפי שמתואר באיור 1.

סקירה כללית של Jack.

איור 1. סקירה כללית של Jack.

פורמט הספרייה של Jack

ל-Jack יש פורמט קובץ משלו, .jack, שמכיל את קוד ה-dex המקודד מראש של הספרייה, ומאפשר הידור מהיר יותר (pre-dex).

תוכן הקובץ של ספריית Jack.

איור 2. תוכן הקובץ של ספריית Jack.

Jill

כפי שמוצג באיור הבא, הכלי Jill מתרגם את הספריות הקיימות של .jar לפורמט הספרייה החדש.

תהליך עבודה לייבוא ספריית 'jar.' קיימת.

איור 3. תהליך עבודה לייבוא ספריית .jar קיימת.

שרת הידור של Jack

בפעם הראשונה שמשתמשים ב-Jack, מופעל במחשב שרת מקומי של Jack לעיבוד. השרת הזה:

  • מאפשרת להאיץ את התהליך באופן מהותי, כי היא מונעת הפעלה של JVM חדש של JRE מארח, טעינת קוד Jack, אתחול של Jack והפעלה מחדש של JIT בכל פעם שמתבצעת הידור. בנוסף, הוא מספק זמני הידור מצוינים במהלך הידור של קטעים קטנים (לדוגמה, במצב מצטבר).
  • זהו פתרון לטווח קצר לצורך בקרה על מספר הקומפילציות המקבילות של Jack. השרת מונע עומס יתר במחשב (בעיה בזיכרון או בדיסק) על ידי הגבלת מספר הידור במקביל.

שרת Jack נכבה מעצמו אחרי פרק זמן של חוסר פעילות, בלי שנעשה בו הידור. הוא משתמש בשתי יציאות TCP בממשק localhost ולא זמין באופן חיצוני. אפשר לשנות את כל הפרמטרים (מספר הידור במקביל, זמן קצוב לתפוגה, מספר יציאות וכו') על ידי עריכת הקובץ $HOME/.jack.

קובץ $HOME/.jack

קובץ $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

בעיה פעולה
המחשב לא מגיב במהלך הידור או שהידורים של Jack נכשלים עם שגיאת Out of memory כדי לצמצם את מספר הסיכומים של Jack שנוצרים בו-זמנית, עורכים את $HOME/.jack ומשנים את SERVER_NB_COMPILE לערך נמוך יותר.
קובצי הידור נכשלים ב-Cannot launch background server הסיבה הסבירה ביותר היא שכבר נעשה שימוש ביציאות TCP במחשב. כדי לשנות את היציאות, עורכים את $HOME/.jack (המשתנים SERVER_PORT_SERVICE ו-SERVER_PORT_ADMIN). כדי לבטל את החסימה, משביתים את שרת הידור Jack על ידי עריכת הקובץ $HOME/.jack ושינוי הערך של SERVER ל-false. לצערנו, הפעולה הזו תאט את תהליך ה-compilation באופן משמעותי, ויכול להיות שתצטרכו להפעיל את make -j עם בקרת עומס (אפשרות -l ב-make).
ה-compilation נתקע בלי התקדמות כדי לבטל את החסימה, מבטלים את הפעולה של שרת הרקע של Jack באמצעות jack-admin kill-server ואז מסירים את הספריות הזמניות שמכילות את jack-$USER מהספרייה הזמנית (/tmp או $TMPDIR).

איתור היומן של Jack

אם הרצתם את הפקודה make עם יעד dist, יומן 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 כדי לקמפל את העץ (או את הפרויקט) ולצרף את הפלט והשגיאה הרגילים. כדי להסיר יומני build מפורטים, מריצים את הפקודה:

unset ANDROID_JACK_EXTRA_ARGS

מגבלות על שקע הטעינה

כברירת מחדל, רק משתמש אחד במחשב יכול להשתמש בשרת Jack. כדי לתמוך במשתמשים נוספים, בוחרים מספרי יציאה שונים לכל משתמש ומשנים את SERVER_NB_COMPILE בהתאם. אפשר גם להשבית את שרת Jack על ידי הגדרת SERVER=false ב-$HOME/.jack. ה-CTS נאסף לאט בגלל השילוב הנוכחי של vm-tests-tf. אין תמיכה בכלים לטיפול בקוד בייט (כמו JaCoCo).

שימוש ב-Jack

Jack תומך בשפת התכנות Java 1.7 ומשלב את התכונות הנוספות שמתוארות בהמשך.

Pre-dex

כשיוצרים קובץ ספרייה של Jack, ה-.dex של הספרייה נוצר ונשמר בתוך קובץ הספרייה .jack כ-pre-dex. בתהליך ה-compilation, Jack משתמש מחדש ב-pre-dex מכל ספרייה. כל הספריות מוכנות מראש.

ספריות Jack עם pre-dex.

איור 4. ספריות Jack עם pre-dex.

Jack לא משתמש שוב בספרייה לפני ה-dex אם נעשה שימוש בהקטנה, בהסתרה או באריזה מחדש בתהליך ההידור.

הידור מצטבר

הידור מצטבר פירושו שרק הרכיבים ששונו מאז הידור הקודם (והיחסים שלהם) עוברים הידור מחדש. הידור מצטבר יכול להיות מהיר יותר באופן משמעותי מהידור מלא כשהשינויים מוגבלים לקבוצה של רכיבים.

הידור מצטבר מושבת כברירת מחדל (והוא מושבת באופן אוטומטי כשמפעילים את התכונות 'צמצום קוד', 'ערפול קוד', 'אריזה מחדש' או 'קוד מדור קודם של multi-dex'). כדי להפעיל גרסאות build מצטברות, מוסיפים את השורה הבאה לקובץ Android.mk של הפרויקט שרוצים ליצור לו גרסאות build מצטברות:

LOCAL_JACK_ENABLED := incremental

כיווץ וערפול קוד

Jack משתמש בקובצי תצורה של ProGuard כדי לאפשר צמצום והסתרה.

בין האפשרויות הנפוצות:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (יש תמיכה רק בקובץ jar אחד של פלט)
  • -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 (ג'ק לא מבצע אימות מראש)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

אריזה מחדש

ג'ק משתמש בקובצי תצורה של jarjar כדי לבצע אריזה מחדש. Jack תואם לסוגים של כללי 'rule', אבל לא לסוגים של כללי 'zap' או 'keep'.

תמיכה ב-Multidex

ב-Jack יש תמיכה מובנית בתמיכה ב-multidex מדור קודם. קובצי dex מוגבלים ל-65,000 שיטות, ולכן אפליקציות עם יותר מ-65,000 שיטות צריכות להיות מחולקות למספר קובצי dex. למידע נוסף, ראו הפעלת multidex לאפליקציות עם יותר מ-64,000 שיטות