کامپایل با جک (AOSP 6.0 - 8.1)

جک (Jack) ابزار پیش‌فرض ساخت اندروید برای اندروید ۶.۰ تا ۸.۱ است.

جک یک زنجیره ابزار اندروید است که سورس جاوا را به بایت‌کد dex اندروید کامپایل می‌کند. برای استفاده از جک لازم نیست کار متفاوتی انجام دهید - فقط از دستورات استاندارد makefile خود برای کامپایل درخت یا پروژه خود استفاده کنید. اندروید ۸.۱ آخرین نسخه‌ای است که از جک استفاده می‌کند.

درباره جک

جک مطابق شکل ۱ عمل می‌کند.

نمای کلی جک.

شکل ۱. نمای کلی جک.

قالب کتابخانه جک

جک فرمت فایل .jack مخصوص به خود را دارد که شامل کد dex از پیش کامپایل شده برای کتابخانه است و امکان کامپایل سریع‌تر (pre-dex) را فراهم می‌کند.

محتویات فایل کتابخانه جک.

شکل ۲. محتویات فایل کتابخانه جک.

جیل

همانطور که در شکل زیر نشان داده شده است، ابزار Jill کتابخانه‌های .jar موجود را به فرمت کتابخانه جدید ترجمه می‌کند.

گردش کار برای وارد کردن یک کتابخانه `jar.` موجود.

شکل ۳. گردش کار برای وارد کردن یک کتابخانه .jar موجود.

سرور کامپایل جک

اولین باری که جک استفاده می‌شود، یک سرور کامپایل جک محلی روی رایانه شما راه‌اندازی می‌شود. این سرور:

  • به دلیل جلوگیری از اجرای JRE JVM میزبان جدید، بارگذاری کد Jack، مقداردهی اولیه Jack و گرم کردن JIT در هر کامپایل، سرعت ذاتی را افزایش می‌دهد. همچنین در کامپایل‌های کوچک (مثلاً در حالت افزایشی) زمان کامپایل بسیار خوبی را فراهم می‌کند.
  • یک راه حل کوتاه مدت برای کنترل تعداد کامپایل‌های موازی Jack است. سرور از بارگذاری بیش از حد کامپیوتر شما (مشکل حافظه یا دیسک) جلوگیری می‌کند زیرا تعداد کامپایل‌های موازی را محدود می‌کند.

سرور Jack پس از مدتی بیکاری و بدون هیچ کامپایلی، خود را خاموش می‌کند. این سرور از دو پورت TCP در رابط میزبان محلی استفاده می‌کند و از خارج در دسترس نیست. همه پارامترها (تعداد کامپایل‌های موازی، زمان انقضا، شماره پورت‌ها و غیره) را می‌توان با ویرایش فایل $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 روی میزبان را تنظیم می‌کند. به طور پیش‌فرض، این متغیر می‌تواند توسط متغیر محیطی سربارگذاری شود.

عیب‌یابی کامپایل‌های جک

مشکل اکشن
رایانه شما هنگام کامپایل کردن از کار می‌افتد یا با خطای «حافظه خالی است» در کامپایل‌های جک مواجه می‌شوید که کار نمی‌کنند. با ویرایش $HOME/.jack ‎ و تغییر SERVER_NB_COMPILE به مقداری کمتر، تعداد کامپایل‌های همزمان Jack را کاهش دهید.
کامپایل‌ها در سرور پس‌زمینه اجرا نمی‌شوند. محتمل‌ترین علت این است که پورت‌های TCP از قبل روی رایانه شما استفاده می‌شوند. با ویرایش $HOME/.jack (متغیرهای SERVER_PORT_SERVICE و SERVER_PORT_ADMIN ) پورت‌ها را تغییر دهید. برای رفع انسداد، سرور کامپایل Jack را با ویرایش $HOME/.jack و تغییر SERVER به false غیرفعال کنید. متأسفانه این کار سرعت کامپایل شما را به میزان قابل توجهی کاهش می‌دهد و ممکن است شما را مجبور به اجرای make -j با کنترل بار (گزینه -l از make ) کند.
کامپایل بدون هیچ پیشرفتی گیر می‌کند برای رفع انسداد این وضعیت، سرور پس‌زمینه Jack را با استفاده از jack-admin kill-server از کار بیندازید ( kill کنید) و سپس دایرکتوری‌های موقت موجود در jack-$USER از دایرکتوری موقت خود ( /tmp یا $TMPDIR ) را حذف کنید.

جک لاگ را پیدا کنید

اگر دستور 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 برای کامپایل درخت (یا پروژه خود) و پیوست کردن خروجی استاندارد و خطا استفاده کنید. برای حذف گزارش‌های ساخت دقیق، دستور زیر را اجرا کنید:

unset ANDROID_JACK_EXTRA_ARGS

محدودیت‌های جک

به طور پیش‌فرض، سرور Jack فقط می‌تواند توسط یک کاربر در یک کامپیوتر استفاده شود. برای پشتیبانی از کاربران بیشتر، شماره پورت‌های مختلفی را برای هر کاربر انتخاب کنید و SERVER_NB_COMPILE را بر اساس آن تنظیم کنید. همچنین می‌توانید سرور Jack را با تنظیم SERVER=false در $HOME/.jack غیرفعال کنید. کامپایل CTS به دلیل ادغام فعلی vm-tests-tf کند است. ابزارهای دستکاری بایت‌کد (مانند JaCoCo) پشتیبانی نمی‌شوند.

از جک استفاده کنید

جک از زبان برنامه‌نویسی جاوا ۱.۷ پشتیبانی می‌کند و ویژگی‌های اضافی شرح داده شده در زیر را در خود جای داده است.

پیش دکس

هنگام تولید یک فایل کتابخانه Jack، فایل .dex کتابخانه تولید شده و به عنوان pre-dex در داخل فایل کتابخانه .jack ذخیره می‌شود. هنگام کامپایل، Jack از pre-dex هر کتابخانه دوباره استفاده می‌کند. همه کتابخانه‌ها pre-dex شده‌اند.

کتابخانه‌های جک با قابلیت pre-dex.

شکل ۴. کتابخانه‌های جک با pre-dex.

اگر در کامپایل از کوچک‌سازی، مبهم‌سازی یا بسته‌بندی مجدد استفاده شود، جک از pre-dex کتابخانه دوباره استفاده نمی‌کند.

کامپایل افزایشی

کامپایل افزایشی به این معنی است که فقط اجزایی که از آخرین کامپایل (و وابستگی‌های آنها) لمس شده‌اند، دوباره کامپایل می‌شوند. کامپایل افزایشی می‌تواند به طور قابل توجهی سریع‌تر از یک کامپایل کامل باشد، زمانی که تغییرات به مجموعه‌ای از اجزا محدود می‌شوند.

کامپایل افزایشی به طور پیش‌فرض غیرفعال است (و هنگام فعال شدن shrinking، obfuscation، repackaging یا multi-dex legacy به طور خودکار غیرفعال می‌شود). برای فعال کردن buildهای افزایشی، خط زیر را به فایل Android.mk پروژه‌ای که می‌خواهید به صورت افزایشی بسازید اضافه کنید:

LOCAL_JACK_ENABLED := incremental

کوچک‌سازی و مبهم‌سازی

جک از فایل‌های پیکربندی 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 (جک بهینه‌سازی نمی‌کند)
  • -dontpreverify (جک preverify نمی‌کند)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

بسته بندی مجدد

جک از فایل‌های پیکربندی jarjar برای انجام بسته‌بندی مجدد استفاده می‌کند. در حالی که جک با انواع قوانین "rule" سازگار است، با انواع قوانین "zap" یا "keep" سازگار نیست.

پشتیبانی از چندرسانه‌ای

جک از multidex داخلی و قدیمی پشتیبانی می‌کند. از آنجا که فایل‌های dex به متدهای ۶۵ کیلوبایتی محدود هستند، برنامه‌هایی با متدهای بیش از ۶۵ کیلوبایت باید به چندین فایل dex تقسیم شوند. برای جزئیات بیشتر، به فعال کردن multidex برای برنامه‌هایی با متدهای بیش از ۶۴ کیلوبایت مراجعه کنید.