Android 12-এ Java মডিউলের জন্য DEX ফাইল (dexpreopt)-এর AOT কম্পাইলেশন
সংক্রান্ত বিল্ড সিস্টেম পরিবর্তন করা হয়েছে, যেগুলির <uses-library>
ডিপেন্ডেন্সি আছে। কিছু ক্ষেত্রে, এই বিল্ড সিস্টেমের পরিবর্তনগুলি বিল্ড ভেঙে
দিতে পারে। এই পৃষ্ঠা ব্যবহার করে ব্রেকের জন্য প্রস্তুতি নিন এবং এই পৃষ্ঠায় দেওয়া রেসিপি অনুসরণ করে
সেগুলি ঠিক করুন ও মিটিগেট করুন।
Dexpreopt হল Java লাইব্রেরি ও অ্যাপের সময়ের আগে কম্পাইলেশনের প্রসেস। বিল্ড করার সময় হোস্ট মেশিনে Dexpreopt হয় (dexopt-এর বিপরীতে, যা ডিভাইসে হয়)। Java মডিউল (কোনও লাইব্রেরি বা অ্যাপ) দ্বারা ব্যবহৃত শেয়ার করা লাইব্রেরি ডিপেন্ডেন্সির স্ট্রাকচারকে ক্লাস লোডার কনটেক্সট (CLC) বলা হয়। dexpreopt-এর নির্ভুলতা নিশ্চিত করতে, বিল্ড-টাইম এবং রান-টাইম CLC অবশ্যই একই হতে হবে। বিল্ড-টাইম CLC হল dex2oat কম্পাইলার যা dexpreopt টাইমে ব্যবহার করে (এটি ODEX ফাইলে রেকর্ড করা হয়) এবং রান-টাইম CLC হল সেই প্রসঙ্গ যেখানে প্রিকম্পাইল করা কোড ডিভাইসে লোড করা হয়।
সঠিকতা ও পারফর্ম্যান্সের কারণে এই বিল্ড-টাইম ও রান-টাইম CLC-কে অবশ্যই একই হতে হবে। সঠিকভাবে কাজ করার জন্য, ডুপ্লিকেট ক্লাস ম্যানেজ করা প্রয়োজন। রানটাইমে শেয়ার করা লাইব্রেরি ডিপেন্ডেন্সি যদি কম্পাইলেশনের জন্য ব্যবহৃত ডিপেন্ডেন্সি থেকে আলাদা হয়, তাহলে কিছু ক্লাস আলাদাভাবে সমাধান করা হতে পারে, যার ফলে রানটাইম বাগ হতে পারে। এছাড়াও, পারফর্ম্যান্সের উপর ডুপ্লিকেট ক্লাসের জন্য রানটাইম চেকের প্রভাব পড়ে।
প্রভাবিত ব্যবহারের উদাহরণ
প্রথম বুট হল প্রধান ব্যবহারিক ক্ষেত্র যা এই পরিবর্তনগুলির দ্বারা প্রভাবিত হয়: ART যদি বিল্ড-টাইম এবং রান-টাইম CLC-এর মধ্যে কোনও অমিল শনাক্ত করে, তাহলে এটি dexpreopt আর্টিফ্যাক্ট বাতিল করে এবং পরিবর্তে dexopt চালায়। পরবর্তী বুটের জন্য এটি ঠিক আছে কারণ অ্যাপগুলি ব্যাকগ্রাউন্ডে dexopt করা এবং ডিস্কে স্টোর করা যেতে পারে।
Android-এর প্রভাবিত অংশ
এটি সেইসব Java অ্যাপ ও লাইব্রেরিকে প্রভাবিত করে যেগুলির রানটাইম ডিপেন্ডেন্সি অন্য Java লাইব্রেরির উপর থাকে। Android-এ হাজার হাজার অ্যাপ আছে এবং সেগুলির মধ্যে শত শত অ্যাপ শেয়ার করা লাইব্রেরি ব্যবহার করে। পার্টনারদের উপরও প্রভাব পড়ে, কারণ তাদের নিজস্ব লাইব্রেরি ও অ্যাপ আছে।
ব্রেকিং পরিবর্তন
বিল্ড সিস্টেমকে <uses-library> ডিপেন্ডেন্সি সম্পর্কে জানতে হবে, তার পরেই
dexpreopt বিল্ড নিয়ম তৈরি করা যাবে। তবে, এটি সরাসরি ম্যানিফেস্ট অ্যাক্সেস করতে
এবং সেটির মধ্যে থাকা <uses-library>
ট্যাগ পড়তে পারে না, কারণ বিল্ড সিস্টেমকে বিল্ড রুল জেনারেট করার সময়
যেকোনও ফাইল পড়ার অনুমতি দেওয়া হয় না (পারফর্ম্যান্সের কারণে)। এছাড়াও, ম্যানিফেস্টটি
APK বা প্রি-বিল্টের মধ্যে প্যাকেজ করা থাকতে পারে। তাই, <uses-library>
তথ্য অবশ্যই বিল্ড ফাইলে (Android.bp বা Android.mk) থাকতে হবে।
আগে ART একটি বিকল্প পদ্ধতি ব্যবহার করত যা শেয়ার করা লাইব্রেরি সংক্রান্ত নির্ভরতা (&-classpath নামে পরিচিত) উপেক্ষা করত। এটি নিরাপদ ছিল না এবং এর ফলে সূক্ষ্ম বাগ তৈরি হত, তাই Android 12-এ বিকল্প পদ্ধতিটি সরিয়ে দেওয়া
হয়েছে।
এর ফলে, যেসব Java মডিউল তাদের বিল্ড ফাইলে সঠিক <uses-library>
তথ্য প্রদান করে না, সেগুলি বিল্ড ব্রেकेज (বিল্ড-টাইম CLC মিসম্যাচের কারণে হয়) বা ফার্স্ট-বুট টাইম রিগ্রেশন (বুট-টাইম
CLC মিসম্যাচ এবং তারপরে dexopt-এর কারণে হয়) ঘটাতে পারে।
মাইগ্রেশন পাথ
কাজ করছে না এমন বিল্ড ঠিক করতে এইসব ধাপ অনুসরণ করুন:
সেটিংয়ের মাধ্যমে কোনও নির্দিষ্ট প্রোডাক্টের জন্য বিল্ড-টাইম চেক বিশ্বব্যাপী বন্ধ করুন
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := trueপ্রোডাক্ট মেকফাইলে। এটি বিল্ড সংক্রান্ত সমস্যা সমাধান করে (বিশেষ ক্ষেত্রগুলি ছাড়া, যেগুলি ভাঙা অংশ ঠিক করা বিভাগে তালিকাভুক্ত)। তবে, এটি একটি সাময়িক সমাধান এবং এর ফলে বুট-টাইম CLC মিসম্যাচ হতে পারে, যার পরে dexopt হয়।
আপনি গ্লোবালি বিল্ড-টাইম চেক বন্ধ করার আগে, যেসব মডিউল কাজ করেনি সেগুলি ঠিক করুন সেগুলির বিল্ড ফাইলে প্রয়োজনীয়
<uses-library>তথ্য যোগ করুন (বিস্তারিত জানতে ব্রেकेज ঠিক করা দেখুন)। বেশিরভাগ মডিউলের ক্ষেত্রে, এর জন্যAndroid.bp-এ বাAndroid.mk-এ কয়েক লাইন যোগ করতে হয়।প্রতিটি মডিউল পিছু, সমস্যাযুক্ত কেসের জন্য বিল্ড-টাইম চেক ও dexpreopt বন্ধ করুন। dexpreopt বন্ধ করে দিন যাতে বুট করার সময় বাতিল হয়ে যাওয়া আর্টিফ্যাক্টে বিল্ড টাইম ও স্টোরেজ নষ্ট না হয়।
১ নম্বর ধাপে সেট করা
PRODUCT_BROKEN_VERIFY_USES_LIBRARIESআনসেট করে বিশ্বব্যাপী বিল্ড-টাইম চেক আবার চালু করুন; এই পরিবর্তনের পরে বিল্ড ব্যর্থ হওয়া উচিত নয় (২ এবং ৩ নম্বর ধাপের কারণে)।ধাপ ৩-এ আপনি যেসব মডিউল বন্ধ করে দিয়েছেন সেগুলি একটি একটি করে ঠিক করুন, তারপর dexpreopt এবং
<uses-library>চেক আবার চালু করুন। প্রয়োজন হলে, সমস্যার ব্যাপারে অভিযোগ জানান।
Android 12-এ বিল্ড-টাইম <uses-library> চেক এনফোর্স করা হয়।
ভাঙা অংশ ঠিক করা
নির্দিষ্ট ধরনের সমস্যা কীভাবে সমাধান করবেন তা নিম্নলিখিত বিভাগ থেকে জানতে পারবেন।
বিল্ড সংক্রান্ত সমস্যা: CLC মিলছে না
বিল্ড সিস্টেম,
Android.bp বা Android.mk ফাইলের তথ্য এবং ম্যানিফেস্টের মধ্যে বিল্ড-টাইম কোহেরেন্স চেক করে। বিল্ড সিস্টেম ম্যানিফেস্ট পড়তে
পারছে না, তবে এটি ম্যানিফেস্ট পড়ার জন্য বিল্ড নিয়ম তৈরি করতে পারে (প্রয়োজন হলে APK থেকে
এটি এক্সট্র্যাক্ট করে) এবং <uses-library> ট্যাগকে ম্যানিফেস্টের মধ্যে
বিল্ড ফাইলের <uses-library> তথ্যের সাথে তুলনা করতে পারে। চেক করা না গেলে,
সমস্যাটি এইরকম দেখতে হয়:
error: mismatch in the <uses-library> tags between the build system and the manifest:
- required libraries in build system: []
vs. in the manifest: [org.apache.http.legacy]
- optional libraries in build system: []
vs. in the manifest: [com.x.y.z]
- tags in the manifest (.../X_intermediates/manifest/AndroidManifest.xml):
<uses-library android:name="com.x.y.z"/>
<uses-library android:name="org.apache.http.legacy"/>
note: the following options are available:
- to temporarily disable the check on command line, rebuild with RELAX_USES_LIBRARY_CHECK=true (this will set compiler filter "verify" and disable AOT-compilation in dexpreopt)
- to temporarily disable the check for the whole product, set PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true in the product makefiles
- to fix the check, make build system properties coherent with the manifest
- see build/make/Changes.md for details
সমস্যার মেসেজে যেমন বলা হয়েছে, একাধিক সমাধান আছে, যা নির্ভর করে জরুরি অবস্থার উপর:
- সাময়িক প্রোডাক্ট-ওয়াইড ফিক্সের জন্য, প্রোডাক্ট মেকফাইলে
PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := trueসেট করুন। বিল্ড-টাইম কোহেরেন্স চেক এখনও করা হয়, তবে চেক ব্যর্থ হওয়ার অর্থ বিল্ড ব্যর্থ হওয়া নয়। এর পরিবর্তে, চেক ব্যর্থ হলে, বিল্ড সিস্টেম dex2oat কম্পাইলার ফিল্টারকে dexpreopt-এverify-এ ডাউনগ্রেড করে, যা এই মডিউলের জন্য AOT-কম্পাইলেশন সম্পূর্ণভাবে বন্ধ করে দেয়। - দ্রুত, গ্লোবাল কমান্ড-লাইন সংক্রান্ত সমস্যার সমাধান করতে, এনভায়রনমেন্ট ভেরিয়েবল
RELAX_USES_LIBRARY_CHECK=trueব্যবহার করুন। এটিPRODUCT_BROKEN_VERIFY_USES_LIBRARIES-এর মতোই কাজ করে, তবে কমান্ড-লাইনে ব্যবহার করার জন্য তৈরি করা হয়েছে। এনভায়রনমেন্ট ভেরিয়েবল প্রোডাক্ট ভেরিয়েবলকে ওভাররাইড করে। - সমস্যার মূল কারণের সমাধান করতে, বিল্ড সিস্টেমকে ম্যানিফেস্টে থাকা
<uses-library>ট্যাগ সম্পর্কে সচেতন করুন। সমস্যার মেসেজ পরীক্ষা করে দেখা যায় যে কোন লাইব্রেরির জন্য সমস্যা হয়েছে (যেমন,AndroidManifest.xmlবা APK-এর মধ্যে থাকা ম্যানিফেস্ট পরীক্ষা করে দেখা যায়, যা `aapt dump badging $APK | grep uses-library` দিয়ে চেক করা যায়)।
Android.bp মডিউলের জন্য:
মডিউলের
libsপ্রপার্টিতে অনুপস্থিত লাইব্রেরি খুঁজুন। এটি থাকলে, Soong সাধারণত এই ধরনের লাইব্রেরি অটোমেটিক যোগ করে, তবে এই বিশেষ ক্ষেত্রে তা করে না:- লাইব্রেরিটি SDK লাইব্রেরি নয় (এটি
java_sdk_library-এর পরিবর্তেjava_libraryহিসেবে সংজ্ঞায়িত করা হয়েছে )। - লাইব্রেরির মডিউল নামের (বিল্ড সিস্টেমে) থেকে লাইব্রেরির নাম (ম্যানিফেস্টে) আলাদা।
সাময়িকভাবে এটি ঠিক করতে,
Android.bpলাইব্রেরি ডেফিনিশনেprovides_uses_lib: "<library-name>"যোগ করুন। দীর্ঘমেয়াদী সমাধানের জন্য, অন্তর্নিহিত সমস্যার সমাধান করুন: লাইব্রেরিকে SDK লাইব্রেরিতে কনভার্ট করুন অথবা এর মডিউলের নাম পরিবর্তন করুন।- লাইব্রেরিটি SDK লাইব্রেরি নয় (এটি
আগের ধাপে সমাধান না হয়ে থাকলে, মডিউলের
Android.bpডেফিনিশনে প্রয়োজনীয় লাইব্রেরির জন্যuses_libs: ["<library-module-name>"]অথবা ঐচ্ছিক লাইব্রেরির জন্যoptional_uses_libs: ["<library-module-name>"]যোগ করুন। এইসব প্রপার্টি মডিউলের নামের একটি তালিকা গ্রহণ করে। তালিকায় লাইব্রেরির আপেক্ষিক ক্রম ম্যানিফেস্টের ক্রমের মতোই হতে হবে।
Android.mk মডিউলের জন্য:
লাইব্রেরির মডিউল নামের (বিল্ড সিস্টেমে) থেকে আলাদা কোনও লাইব্রেরি নাম (ম্যানিফেস্টে) আছে কিনা তা চেক করে দেখুন। যদি তা হয়, তাহলে লাইব্রেরির
Android.mkফাইলেLOCAL_PROVIDES_USES_LIBRARY := <library-name>যোগ করে সাময়িকভাবে এই সমস্যার সমাধান করুন অথবা লাইব্রেরিরAndroid.bpফাইলেprovides_uses_lib: "<library-name>"যোগ করুন (দুটি ক্ষেত্রেই এটি সম্ভব কারণAndroid.mkমডিউলAndroid.bpলাইব্রেরির উপর নির্ভর করতে পারে)। দীর্ঘমেয়াদী সমাধানের জন্য, মূল সমস্যার সমাধান করুন: লাইব্রেরি মডিউলের নাম পরিবর্তন করুন।প্রয়োজনীয় লাইব্রেরির জন্য
LOCAL_USES_LIBRARIES := <library-module-name>যোগ করুন; মডিউলেরAndroid.mkডেফিনিশনে ঐচ্ছিক লাইব্রেরির জন্যLOCAL_OPTIONAL_USES_LIBRARIES := <library-module-name>যোগ করুন। এইসব প্রপার্টি মডিউলের নামের তালিকা গ্রহণ করে। তালিকায় লাইব্রেরির আপেক্ষিক ক্রম ম্যানিফেস্টের মতোই হতে হবে।
বিল্ড সংক্রান্ত সমস্যা: লাইব্রেরি পাথ অজানা
বিল্ড সিস্টেম যদি <uses-library> DEX jar-এর পাথ খুঁজে না পায় (হোস্ট মেশিনে
বিল্ড-টাইম পাথ অথবা ডিভাইসে ইনস্টল পাথ), তাহলে সাধারণত
বিল্ড করা যায় না। পাথ খুঁজে না পাওয়ার অর্থ হল, লাইব্রেরিটি কোনও অপ্রত্যাশিত উপায়ে কনফিগার করা হয়েছে।
সমস্যাযুক্ত
মডিউলের জন্য dexpreopt বন্ধ করে সাময়িকভাবে বিল্ড ঠিক করুন।
Android.bp (মডিউল প্রপার্টি):
enforce_uses_libs: false,
dex_preopt: {
enabled: false,
},
Android.mk (মডিউল ভেরিয়েবল):
LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_DEX_PREOPT := false
কাজ করছে না এমন কোনও পরিস্থিতি তদন্ত করতে বাগ ফাইল করুন।
বিল্ড সংক্রান্ত সমস্যা: লাইব্রেরি ডিপেন্ডেন্সি নেই
Y-এর জন্য বিল্ড
ফাইলে মডিউল Y-এর ম্যানিফেস্ট থেকে <uses-library> X যোগ করার চেষ্টা করলে, X-এর অনুপস্থিতির কারণে বিল্ড সংক্রান্ত সমস্যা হতে পারে।
Android.bp মডিউলের জন্য এটি হল একটি নমুনা সমস্যা সংক্রান্ত মেসেজ:
"Y" depends on undefined module "X"
Android.mk মডিউলের জন্য এটি একটি স্যাম্পেল ত্রুটি মেসেজ:
'.../JAVA_LIBRARIES/com.android.X_intermediates/dexpreopt.config', needed by '.../APPS/Y_intermediates/enforce_uses_libraries.status', missing and no known rule to make it
এই ধরনের সমস্যার একটি সাধারণ কারণ হল, কোনও লাইব্রেরির নাম তার
সংশ্লিষ্ট মডিউলের নামের থেকে আলাদা হলে, বিল্ড সিস্টেমে এই সমস্যা হয়। যেমন, ম্যানিফেস্টের
<uses-library> এন্ট্রি com.android.X হলে, কিন্তু লাইব্রেরি মডিউলের নাম
শুধুমাত্র X হলে, এর ফলে সমস্যা হয়। এই সমস্যার সমাধান করতে, বিল্ড সিস্টেমকে বলুন যে
X নামের মডিউলটি com.android.X নামের একটি <uses-library> প্রদান করে।
এটি Android.bp লাইব্রেরির (মডিউল প্রপার্টি) একটি উদাহরণ:
provides_uses_lib: “com.android.X”,
এটি Android.mk লাইব্রেরির (মডিউল ভেরিয়েবল) একটি উদাহরণ:
LOCAL_PROVIDES_USES_LIBRARY := com.android.X
বুট-টাইম CLC ম্যাচ না করা
প্রথম বুটে, CLC মিসম্যাচ সম্পর্কিত মেসেজের জন্য logcat সার্চ করুন, যেমন নিচে দেখানো হয়েছে:
$ adb wait-for-device && adb logcat \
| grep -E 'ClassLoaderContext [a-z ]+ mismatch' -A1
আউটপুটে এখানে দেখানো ফর্মের মেসেজ থাকতে পারে:
[...] W system_server: ClassLoaderContext shared library size mismatch Expected=..., found=... (PCL[]... | PCL[]...)
[...] I PackageDexOptimizer: Running dexopt (dexoptNeeded=1) on: ...
আপনি CLC অমিল সংক্রান্ত সতর্কতা পেলে, ত্রুটিপূর্ণ মডিউলের জন্য dexopt কমান্ড খুঁজুন। এটি ঠিক করতে, মডিউলের জন্য বিল্ড-টাইম চেক পাস হয়েছে কিনা তা নিশ্চিত করুন। সেটি কাজ না করলে, আপনারটি হয়ত এমন একটি বিশেষ কেস যা বিল্ড সিস্টেমের (যেমন, লাইব্রেরি নয়, অন্য APK লোড করে এমন অ্যাপ) সাথে কাজ করে না। বিল্ড সিস্টেম সব কেস ম্যানেজ করে না, কারণ বিল্ড করার সময় রানটাইমে অ্যাপ কী লোড করবে তা নিশ্চিতভাবে জানা অসম্ভব।
ক্লাস লোডার কনটেক্সট
CLC হল একটি ট্রি-এর মতো স্ট্রাকচার যা ক্লাস-লোডার হায়ারের্কি বর্ণনা করে। বিল্ড সিস্টেম CLC-কে একটি সীমিত অর্থে ব্যবহার করে (এটি শুধুমাত্র লাইব্রেরি কভার করে, APK বা
কাস্টম-ক্লাস লোডার নয়): এটি হল লাইব্রেরির একটি ট্রি যা কোনও লাইব্রেরি বা অ্যাপের সমস্ত <uses-library> ডিপেন্ডেন্সির ট্রানজিটিভ
ক্লোজারকে উপস্থাপন করে। CLC-এর টপলেভেল
এলিমেন্ট হল ম্যানিফেস্টে (ক্লাসপাথ) নির্দিষ্ট করা ডাইরেক্ট <uses-library> ডিপেন্ডেন্সি। CLC ট্রি-এর প্রতিটি নোড হল একটি
<uses-library> নোড যার নিজস্ব <uses-library> সাব-নোড থাকতে পারে।
যেহেতু <uses-library> ডিপেন্ডেন্সি হল একটি ডিরেক্টেড অ্যাসাইক্লিক গ্রাফ এবং
ট্রি নাও হতে পারে, তাই CLC-তে একই লাইব্রেরির জন্য একাধিক সাবট্রি থাকতে পারে। অন্য
কথায়, CLC হল একটি ট্রি হিসেবে "আনফোল্ড" করা ডিপেনডেন্সি গ্রাফ। ডুপ্লিকেশন
শুধুমাত্র লজিক্যাল লেভেলে হয়; আসল অন্তর্নিহিত ক্লাস লোডার ডুপ্লিকেট
হয় না (রানটাইমে প্রতিটি লাইব্রেরির জন্য একটি ক্লাস লোডার ইনস্ট্যান্স থাকে)।
লাইব্রেরি বা অ্যাপের মাধ্যমে ব্যবহৃত জাভা ক্লাস সমাধান করার সময় CLC লাইব্রেরির লুকআপ অর্ডার নির্ধারণ করে। লুকআপ অর্ডার গুরুত্বপূর্ণ কারণ লাইব্রেরিতে ডুপ্লিকেট ক্লাস থাকতে পারে এবং প্রথম ম্যাচেই ক্লাস সমাধান করা হয়।
অন-ডিভাইস (রান-টাইম) CLC
PackageManager (frameworks/base-এ) ডিভাইসে জাভা মডিউল লোড করার জন্য
CLC তৈরি করে। এটি মডিউলের
ম্যানিফেস্টে <uses-library> ট্যাগ হিসেবে তালিকাভুক্ত লাইব্রেরিগুলিকে টপ-লেভেল CLC এলিমেন্ট হিসেবে যোগ করে।
ব্যবহার করা প্রতিটি লাইব্রেরির জন্য, PackageManager তার সব <uses-library>
ডিপেন্ডেন্সি (সেই লাইব্রেরির ম্যানিফেস্টে ট্যাগ হিসেবে উল্লেখ করা) পায় এবং প্রতিটি ডিপেন্ডেন্সির জন্য একটি
নেস্টেড CLC যোগ করে। এই প্রসেসটি পুনরাবৃত্তিমূলকভাবে চলতে থাকে যতক্ষণ না
তৈরি করা CLC ট্রি-এর সমস্ত লিফ নোড <uses-library> ডিপেন্ডেন্সি ছাড়াই লাইব্রেরি হয়।
PackageManager শুধুমাত্র শেয়ার করা লাইব্রেরি সম্পর্কে জানে। এই ব্যবহারের ক্ষেত্রে শেয়ার করা বলতে
যা বোঝানো হয়েছে তা সাধারণ অর্থ (যেমন, শেয়ার করা বনাম স্ট্যাটিক) থেকে আলাদা। Android-এ,
XML কনফিগে যেসব জাভা শেয়ার করা লাইব্রেরি তালিকাভুক্ত থাকে সেগুলি ডিভাইসে
ইনস্টল করা থাকে (/system/etc/permissions/platform.xml)। প্রতিটি এন্ট্রিতে শেয়ার করা লাইব্রেরির নাম,
এর DEX jar ফাইলের পাথ এবং নির্ভরতা (অন্যান্য শেয়ার করা লাইব্রেরি যা এটি রানটাইমে ব্যবহার করে এবং
এর ম্যানিফেস্টে <uses-library> ট্যাগে নির্দিষ্ট করে) থাকে।
অন্যভাবে বলতে গেলে, এমন দুটি সোর্স থেকে তথ্য পাওয়া যায় যা PackageManager
রানটাইমে CLC তৈরি করতে দেয়: <uses-library> ম্যানিফেস্টে ট্যাগ এবং
XML কনফিগে শেয়ার করা লাইব্রেরি সংক্রান্ত নির্ভরতা।
অন-হোস্ট (বিল্ড-টাইম) CLC
CLC শুধুমাত্র লাইব্রেরি বা অ্যাপ লোড করার সময়ই প্রয়োজন হয় না, এটি কম্পাইল করার সময়ও প্রয়োজন হয়।
কম্পাইলেশন অন-ডিভাইস (dexopt) বা বিল্ড (dexpreopt) চলাকালীন
হতে পারে। যেহেতু dexopt অন-ডিভাইসে হয়, তাই এতে PackageManager-এর (ম্যানিফেস্ট এবং শেয়ার করা লাইব্রেরি ডিপেন্ডেন্সি)
মতো একই তথ্য থাকে।
তবে, Dexpreopt হোস্টেই এবং সম্পূর্ণ আলাদা
এনভায়রনমেন্টে হয় এবং এটি বিল্ড সিস্টেম থেকে একই তথ্য পায়।
তাই, dexpreopt-এর ব্যবহার করা বিল্ড-টাইম CLC এবং
PackageManager-এর ব্যবহার করা রান-টাইম CLC একই জিনিস, তবে দুটি আলাদা উপায়ে গণনা করা হয়।
বিল্ড-টাইম ও রান-টাইম CLC অবশ্যই একই হতে হবে, তা না হলে dexpreopt-এর তৈরি করা AOT-কম্পাইল করা কোড
বাতিল হয়ে যাবে। বিল্ড-টাইম ও
রান-টাইম CLC সমান কিনা তা চেক করতে, dex2oat কম্পাইলার *.odex ফাইলে
(OAT ফাইল হেডারের classpath ফিল্ডে) বিল্ড-টাইম CLC রেকর্ড করে। সেভ করা CLC খুঁজে পেতে, এই
কমান্ড ব্যবহার করুন:
oatdump --oat-file=<FILE> | grep '^classpath = '
বুট করার সময় logcat-এ বিল্ড-টাইম ও রান-টাইম CLC-এর অমিল সংক্রান্ত রিপোর্ট করা হয়। এই কমান্ড দিয়ে সেটি সার্চ করুন:
logcat | grep -E 'ClassLoaderContext [a-z ]+ mismatch'
পারফর্ম্যান্সের জন্য মিল না থাকা ভাল নয়, কারণ এটি লাইব্রেরি বা অ্যাপকে হয় ডেক্সঅপ্টিমাইজ করতে বাধ্য করে অথবা অপ্টিমাইজেশন ছাড়াই রান করায় (যেমন, অ্যাপের কোডকে APK থেকে মেমরিতে এক্সট্র্যাক্ট করতে হতে পারে, এটি একটি খুব ব্যয়বহুল অপারেশন)।
শেয়ার করা লাইব্রেরি ঐচ্ছিক বা বাধ্যতামূলক হতে পারে। dexpreopt-এর দৃষ্টিকোণ থেকে, বিল্ড করার সময় প্রয়োজনীয় লাইব্রেরি থাকতে হবে (এটি
না থাকলে বিল্ড সংক্রান্ত সমস্যা হয়)। বিল্ড টাইমে ঐচ্ছিক লাইব্রেরি থাকতেও পারে, নাও থাকতে পারে: থাকলে, সেটি CLC-তে যোগ করা হয়, dex2oat-এ পাস করা হয় এবং
*.odex ফাইলে রেকর্ড করা হয়। ঐচ্ছিক লাইব্রেরি না থাকলে, সেটি বাদ দেওয়া হয়
এবং CLC-তে যোগ করা হয় না। বিল্ড-টাইম ও
রান-টাইম স্ট্যাটাসের মধ্যে কোনও অমিল থাকলে (ঐচ্ছিক লাইব্রেরি একটি ক্ষেত্রে উপস্থিত থাকলেও অন্যটিতে নেই),
তাহলে বিল্ড-টাইম ও রান-টাইম CLC ম্যাচ করে না এবং কম্পাইল করা কোড
বাতিল হয়ে যায়।
উন্নত বিল্ড সিস্টেমের বিবরণ (ম্যানিফেস্ট ফিক্সার)
কখনও কখনও, কোনও লাইব্রেরি বা অ্যাপের সোর্স ম্যানিফেস্টে <uses-library> ট্যাগ থাকে না। এটি হতে পারে, যেমন, লাইব্রেরি বা অ্যাপের ট্রানজিটিভ ডিপেন্ডেন্সি
অন্য <uses-library> ট্যাগ ব্যবহার করা শুরু করলে এবং লাইব্রেরি বা অ্যাপের
ম্যানিফেস্ট সেটি অন্তর্ভুক্ত করার জন্য আপডেট না করা হলে।
Soong কোনও লাইব্রেরি বা অ্যাপের জন্য কিছু অনুপস্থিত <uses-library> ট্যাগ অটোমেটিক গণনা করতে পারে,
কারণ SDK লাইব্রেরিগুলি লাইব্রেরি বা অ্যাপের ট্রানজিটিভ ডিপেন্ডেন্সি ক্লোজারে থাকে।
ক্লোজারটি প্রয়োজন কারণ লাইব্রেরি (বা অ্যাপ) একটি স্ট্যাটিক লাইব্রেরির উপর নির্ভর করতে পারে
যা একটি SDK লাইব্রেরির উপর নির্ভর করে এবং সম্ভবত আবার অন্য লাইব্রেরির মাধ্যমে ট্রানজিটিভভাবে নির্ভর করতে পারে।
সব <uses-library> ট্যাগ এইভাবে গণনা করা যায় না, তবে সম্ভব হলে, Soong-কে ম্যানিফেস্ট এন্ট্রি অটোমেটিক যোগ করতে দেওয়া
ভাল; এটি কম
ভুল-প্রবণ এবং রক্ষণাবেক্ষণ সহজ করে। যেমন, অনেক অ্যাপ যখন একটি স্ট্যাটিক
লাইব্রেরি ব্যবহার করে যা একটি নতুন <uses-library> ডিপেন্ডেন্সি যোগ করে, তখন সব অ্যাপকে অবশ্যই
আপডেট করতে হবে, যা বজায় রাখা কঠিন।