คอมไพล์ด้วย Jack (AOSP 6.0 - 8.1)

Jack เป็นเครื่องมือสร้างบิลด์ของ Android เริ่มต้นสำหรับ Android 6.0 - 8.1

Jack เป็น Toolchain ของ Android ที่คอมไพล์ซอร์ส Java ลงใน Android dex ไบต์โค้ด การใช้ Jack ไม่จำเป็นต้องดำเนินการใดๆ เพิ่มเติม เพียงแค่ใช้ คำสั่ง getfile มาตรฐานเพื่อคอมไพล์โครงสร้างหรือโปรเจ็กต์ Android 8.1 เป็นรุ่นล่าสุดที่ใช้ Jack

เกี่ยวกับ Jack

แจ็คทำงานดังที่แสดงในรูปที่ 1

ภาพรวม Jack

รูปที่ 1 ภาพรวม Jack

รูปแบบไลบรารี Jack

Jack มีรูปแบบไฟล์ .jack ของตนเองที่มีโค้ด Dex ที่คอมไพล์ไว้ล่วงหน้า สำหรับไลบรารี ทำให้คอมไพล์ได้รวดเร็วยิ่งขึ้น (Pre-dex)

เนื้อหาไฟล์ไลบรารี Jack

รูปที่ 2 เนื้อหาไฟล์ไลบรารี Jack

จิล

ดังที่ปรากฏในภาพต่อไปนี้ เครื่องมือ Jill จะแปลค่าการแปลรหัสที่มีอยู่ ห้องสมุด .jar รายการเป็นรูปแบบห้องสมุดใหม่

เวิร์กโฟลว์การนำเข้าไลบรารี "jar" ที่มีอยู่

รูปที่ 3 เวิร์กโฟลว์การนำเข้าไลบรารี .jar ที่มีอยู่

เซิร์ฟเวอร์การคอมไพล์ Jack

ครั้งแรกที่มีการใช้งาน Jack ได้เปิดตัวเซิร์ฟเวอร์การคอมไพล์ Jack ในเครื่อง คอมพิวเตอร์ เซิร์ฟเวอร์นี้:

  • ทำให้ได้ความเร็วที่แท้จริงเพราะไม่ต้องเปิดตัว JRE JVM สำหรับผู้จัดรายใหม่ การโหลดโค้ดของ Jack, การเริ่มต้น Jack และการอุ่นเครื่องของ JIT ใน ในการรวบรวม และยังให้เวลาการรวบรวมคลิปที่ดีมาก การคอมไพล์ (เช่น ในโหมดเพิ่มขึ้นเรื่อยๆ)
  • เป็นโซลูชันระยะสั้นในการควบคุมจำนวนแจ็คคู่ขนาน ในการรวบรวม เซิร์ฟเวอร์ป้องกันไม่ให้คอมพิวเตอร์ทำงานหนักเกินไป (ปัญหาเกี่ยวกับหน่วยความจำหรือดิสก์) เพราะจำกัดจำนวนการคอมไพล์แบบขนาน

เซิร์ฟเวอร์ Jack จะปิดการทำงานเองหลังจากไม่มีการใช้งานโดยไม่มีการคอมไพล์ อุปกรณ์ใช้พอร์ต TCP 2 พอร์ตในอินเทอร์เฟซ 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 ล้มเหลวเนื่องจากข้อผิดพลาดหน่วยความจำไม่เพียงพอ ลดจำนวนแจ็คพร้อมกันได้ การรวบรวมโดยการแก้ไข $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 Log

หากคุณเรียกใช้คำสั่ง 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 ตามนั้น นอกจากนี้ คุณยังปิดใช้ เซิร์ฟเวอร์ Jack โดยการตั้งค่า SERVER=false ใน $HOME/.jack การคอมไพล์ CTS ช้าเนื่องจากการผสานรวม vm-tests-tf ในปัจจุบัน ไม่รองรับเครื่องมือการจัดการไบต์โค้ด (เช่น JaCoCo)

ใช้ Jack

Jack สนับสนุนภาษาโปรแกรม Java 1.7 และผสานรวมภาษาโปรแกรมเพิ่มเติม ฟีเจอร์ที่อธิบายไว้ด้านล่าง

ก่อนแปลงเพศ

เมื่อสร้างไฟล์ไลบรารี Jack .dex ของไลบรารีคือ สร้างขึ้นและเก็บไว้ในไฟล์ไลบรารี .jack เป็น Pre-dex เมื่อคอมไพล์ Jack จะใช้ Pre-dex จากไลบรารีแต่ละแห่งซ้ำ ไลบรารีทั้งหมด ไฟล์ที่ซ้ำกัน

ไลบรารีของ Jack ที่มี Pre-dex

รูปที่ 4 ไลบรารีของ Jack ที่มี Pre-dex

Jack ไม่ได้ใช้ไฟล์ Pre-dex ของไลบรารีซ้ำหากมีการย่อ ปรับให้ยากต่อการอ่าน (Obfuscate) หรือ มีการใช้การจัดแพ็กเกจใหม่ในการคอมไพล์

การรวบรวมคลิปแบบเพิ่มขึ้นเรื่อยๆ

การคอมไพล์ส่วนเพิ่มหมายถึงเฉพาะคอมโพเนนต์ที่มีการแตะเท่านั้น การคอมไพล์ (และการขึ้นต่อกัน) จะได้รับการคอมไพล์อีกครั้ง สามารถคอมไพล์ส่วนเพิ่ม จะเร็วกว่าการคอมไพล์แบบเต็มรูปแบบ เมื่อจำกัดการเปลี่ยนแปลงไว้ คอมโพเนนต์ต่างๆ

การคอมไพล์แบบเพิ่มขึ้นเรื่อยๆ จะถูกปิดใช้งานโดยค่าเริ่มต้น (และ ปิดใช้งานเมื่อย่อ ปรับให้ยากต่อการอ่าน (Obfuscate) จัดแพ็กเกจใหม่ หรือเก็บมรดกจากหลายดัชนี เปิดอยู่) หากต้องการเปิดใช้บิลด์ส่วนเพิ่ม ให้เพิ่มบรรทัดต่อไปนี้ในส่วน 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 (แจ็คไม่ยืนยันล่วงหน้า)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

การจัดแพ็กเกจใหม่

Jack ใช้ไฟล์การกำหนดค่า jarjar เพื่อทำการจัดแพ็กเกจใหม่ ขณะที่แจ็คกำลัง ใช้ได้กับ "กฎ" ประเภทกฎ ซึ่งใช้ไม่ได้กับ "zap" หรือ "เก็บ" ประเภทกฎ

การสนับสนุน Multidex

Jack มีการรองรับ Multidex ทั้งในตัวและแบบเดิม เนื่องจากไฟล์ dex มีจำกัด เป็น 65,000 เมธอด โดยแอปที่มีเมธอดมากกว่า 65,000 เมธอดจะต้องแยกเป็น Dex หลายรายการ ดูรายละเอียดเพิ่มเติมได้ที่ เปิดใช้ Multidex สำหรับแอปที่มีเมธอดกว่า 64,000 วิธี