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

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

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

מידע על ג'ק

שקע פועל כמו שמוצג באיור 1.

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

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

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

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

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

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

ג'יל

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

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

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

שרת הידור של שקעים

.

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

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

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

קובץ $Home/.jack

קובץ $HOME/.jack מכיל את ההגדרות הבאות למשתני השרת של Jack, בסינטקס bash מלא:

  • SERVER=true מפעיל את תכונת השרת של טל.
  • 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 נכשלים עם שגיאת Out of memory כדי לצמצם את מספר האוספים של Jack בו-זמנית, צריך לערוך את $HOME/.jack ולשנות את SERVER_NB_COMPILE לערך נמוך יותר.
האוספים נכשלים בלא ניתן להפעיל את שרת הרקע הסיבה הסבירה ביותר היא שיציאות TCP כבר נמצאות בשימוש במחשב. כדי לשנות את היציאות, עורכים את $HOME/.jack (המשתנים SERVER_PORT_SERVICE ו-SERVER_PORT_ADMIN). כדי לבטל את החסימה של המצב, משביתים את שרת ההידור של Jack על ידי עריכת $HOME/.jack ושינוי של SERVER ל-false. לצערנו, הפעולה הזו מאטה משמעותית את הידור ויכולה לאלץ אתכם להפעיל את make -j עם בקרת עומס (אפשרות -l מתוך make).
ההידור נתקע בלי התקדמות כדי לבטל את החסימה, צריך להרוג את שרת הרקע של 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

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

שימוש ב-Jack

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

לפני ה-dex

כשיוצרים קובץ ספרייה של Jack, ה-.dex של הספרייה נוצר ונשמר בקובץ הספרייה .jack כ-pre-dex. במהלך ההידור, ג'ק עושה שימוש חוזר בקובץ שלפני ה-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 (יש תמיכה רק בצנצנת פלט אחת)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

אפשרויות הכיווץ כוללות:

  • -dontshrink

האפשרויות לערפול קוד (obfuscation):

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

אלה האפשרויות שהמערכת תתעלם מהן:

  • -dontoptimize (טל לא מבצע אופטימיזציה)
  • -dontpreverify (ג'ק לא מבצע אימות מראש)
  • -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'.

תמיכה ב-Multidex

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