Dexpreopt এবং <uses-library> চেক

Android 12-এ <uses-library> নির্ভরতা আছে এমন Java মডিউলগুলির জন্য DEX ফাইলের (dexpreopt) AOT সংকলনে সিস্টেম পরিবর্তনগুলি তৈরি করা হয়েছে। কিছু ক্ষেত্রে এই বিল্ড সিস্টেম পরিবর্তন বিল্ড ভেঙ্গে দিতে পারে। ভাঙ্গনের জন্য প্রস্তুত করতে এই পৃষ্ঠাটি ব্যবহার করুন এবং সেগুলিকে ঠিক করতে এবং প্রশমিত করতে এই পৃষ্ঠার রেসিপিগুলি অনুসরণ করুন৷

ডেক্সপ্রিওপ্ট হল জাভা লাইব্রেরি এবং অ্যাপের আগাম সংকলনের প্রক্রিয়া। ডেক্সপ্রিওপ্ট বিল্ড টাইমে অন-হোস্ট হয় ( ডেক্সপট এর বিপরীতে, যা ডিভাইসে ঘটে)। একটি জাভা মডিউল (একটি লাইব্রেরি বা একটি অ্যাপ) দ্বারা ব্যবহৃত শেয়ার্ড লাইব্রেরি নির্ভরতার কাঠামোটি এর ক্লাস লোডার প্রসঙ্গ (CLC) নামে পরিচিত। ডেক্সপ্রিওপ্টের সঠিকতার গ্যারান্টি দিতে, বিল্ড-টাইম এবং রান-টাইম সিএলসি অবশ্যই মিলে যাবে। বিল্ড-টাইম CLC হল যা dex2oat কম্পাইলার dexpreopt সময়ে ব্যবহার করে (এটি ODEX ফাইলগুলিতে রেকর্ড করা হয়), এবং রান-টাইম CLC হল সেই প্রেক্ষাপট যেখানে প্রি-কম্পাইল করা কোড ডিভাইসে লোড করা হয়।

এই বিল্ড-টাইম এবং রান-টাইম সিএলসি অবশ্যই সঠিকতা এবং কর্মক্ষমতা উভয়ের কারণেই মিলে যাবে। সঠিকতার জন্য, ডুপ্লিকেট ক্লাস পরিচালনা করা প্রয়োজন। রানটাইমে শেয়ার্ড লাইব্রেরি নির্ভরতাগুলি সংকলনের জন্য ব্যবহৃত লাইব্রেরিগুলির থেকে আলাদা হলে, কিছু ক্লাস আলাদাভাবে সমাধান করা যেতে পারে, যার ফলে সূক্ষ্ম রানটাইম বাগগুলি হতে পারে। ডুপ্লিকেট ক্লাসের জন্য রানটাইম চেক দ্বারা কর্মক্ষমতাও প্রভাবিত হয়।

প্রভাবিত ব্যবহারের ক্ষেত্রে

প্রথম বুট হল প্রধান ব্যবহারের ক্ষেত্রে যা এই পরিবর্তনগুলির দ্বারা প্রভাবিত হয়: যদি ART বিল্ড-টাইম এবং রান-টাইম CLC-এর মধ্যে একটি অমিল শনাক্ত করে, তবে এটি dexpreopt আর্টিফ্যাক্টগুলি প্রত্যাখ্যান করে এবং পরিবর্তে dexopt চালায়। পরবর্তী বুটগুলির জন্য এটি ঠিক কারণ অ্যাপগুলিকে ব্যাকগ্রাউন্ডে ডিক্সপ্ট করা যায় এবং ডিস্কে সংরক্ষণ করা যায়।

অ্যান্ড্রয়েডের প্রভাবিত এলাকা

এটি অন্যান্য জাভা লাইব্রেরিতে রানটাইম নির্ভরতা আছে এমন সমস্ত জাভা অ্যাপ এবং লাইব্রেরিকে প্রভাবিত করে। অ্যান্ড্রয়েডের হাজার হাজার অ্যাপ রয়েছে এবং সেগুলির শত শত শেয়ার করা লাইব্রেরি ব্যবহার করে। অংশীদাররাও প্রভাবিত হয়, কারণ তাদের নিজস্ব লাইব্রেরি এবং অ্যাপ রয়েছে।

বিরতি পরিবর্তন

dexpreopt বিল্ড নিয়ম তৈরি করার আগে বিল্ড সিস্টেমকে <uses-library> নির্ভরতা জানতে হবে। যাইহোক, এটি সরাসরি ম্যানিফেস্ট অ্যাক্সেস করতে পারে না এবং এটিতে <uses-library> ট্যাগগুলি পড়তে পারে না, কারণ বিল্ড সিস্টেমটি যখন বিল্ড নিয়ম তৈরি করে (কর্মক্ষমতার কারণে) নির্বিচারে ফাইলগুলি পড়ার অনুমতি দেয় না। তদুপরি, ম্যানিফেস্টটি একটি APK বা পূর্বনির্মাণের ভিতরে প্যাকেজ করা হতে পারে। অতএব, <uses-library> তথ্য অবশ্যই বিল্ড ফাইলগুলিতে উপস্থিত থাকতে হবে ( Android.bp বা Android.mk )।

পূর্বে ART একটি সমাধান ব্যবহার করত যা ভাগ করা লাইব্রেরি নির্ভরতাকে উপেক্ষা করত (যা &-classpath নামে পরিচিত)। এটি অনিরাপদ ছিল এবং সূক্ষ্ম বাগ সৃষ্টি করেছিল, তাই অ্যান্ড্রয়েড 12 এ সমাধানটি সরিয়ে দেওয়া হয়েছিল।

ফলস্বরূপ, জাভা মডিউল যেগুলি তাদের বিল্ড ফাইলগুলিতে সঠিক <uses-library> তথ্য প্রদান করে না সেগুলি বিল্ড ব্রেকেজ (একটি বিল্ড-টাইম CLC অমিলের কারণে) বা প্রথম-বুট টাইম রিগ্রেশন (বুট-টাইম CLC দ্বারা সৃষ্ট) হতে পারে dexopt দ্বারা অনুসৃত অমিল)।

অভিবাসন পথ

একটি ভাঙা বিল্ড ঠিক করতে এই পদক্ষেপগুলি অনুসরণ করুন:

  1. বিশ্বব্যাপী সেট করে একটি নির্দিষ্ট পণ্যের জন্য বিল্ড-টাইম চেক অক্ষম করুন

    PRODUCT_BROKEN_VERIFY_USES_LIBRARIES := true

    পণ্যের মেকফাইলে। এটি বিল্ড ত্রুটিগুলি ঠিক করে (বিশেষ ক্ষেত্রে ছাড়া, ফিক্সিং ব্রেকেজ বিভাগে তালিকাভুক্ত)। যাইহোক, এটি একটি অস্থায়ী সমাধান, এবং এটি dexopt দ্বারা অনুসরণ করে বুট-টাইম CLC অমিল হতে পারে।

  2. আপনার বিল্ড-টাইম চেক বিশ্বব্যাপী অক্ষম করার আগে ব্যর্থ হওয়া মডিউলগুলিকে তাদের বিল্ড ফাইলগুলিতে প্রয়োজনীয় <uses-library> তথ্য যোগ করে ঠিক করুন (বিশদ বিবরণের জন্য বিচ্ছেদের সংশোধন দেখুন)। বেশিরভাগ মডিউলের জন্য এর জন্য Android.bp বা Android.mk এ কয়েকটি লাইন যোগ করা প্রয়োজন।

  3. প্রতি-মডিউল ভিত্তিতে, সমস্যাযুক্ত ক্ষেত্রে বিল্ড-টাইম চেক এবং ডেক্সপ্রিওপ্ট অক্ষম করুন। dexpreopt অক্ষম করুন যাতে আপনি বুট করার সময় প্রত্যাখ্যাত আর্টিফ্যাক্টগুলিতে বিল্ড সময় এবং স্টোরেজ নষ্ট করবেন না।

  4. ধাপ 1 এ সেট করা PRODUCT_BROKEN_VERIFY_USES_LIBRARIES আনসেট করে বিশ্বব্যাপী বিল্ড-টাইম চেক পুনরায়-সক্ষম করুন; এই পরিবর্তনের পরে বিল্ডটি ব্যর্থ হওয়া উচিত নয় (পদক্ষেপ 2 এবং 3 এর কারণে)।

  5. আপনি ধাপ 3-এ অক্ষম করা মডিউলগুলিকে এক সময়ে ঠিক করুন, তারপরে 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 মডিউলগুলির জন্য:

  1. মডিউলের libs সম্পত্তিতে অনুপস্থিত লাইব্রেরি সন্ধান করুন। যদি এটি থাকে, Soong সাধারণত এই ধরনের বিশেষ ক্ষেত্রে ব্যতীত স্বয়ংক্রিয়ভাবে এই ধরনের লাইব্রেরি যোগ করে:

    • লাইব্রেরিটি একটি SDK লাইব্রেরি নয় (এটি java_sdk_library এর পরিবর্তে java_library হিসাবে সংজ্ঞায়িত করা হয়েছে)।
    • লাইব্রেরির মডিউল নাম (বিল্ড সিস্টেমে) থেকে আলাদা লাইব্রেরির নাম (মেনিফেস্টে) রয়েছে।

    এটি সাময়িকভাবে ঠিক করতে, Android.bp লাইব্রেরির সংজ্ঞায় provides_uses_lib: "<library-name>" যোগ করুন। দীর্ঘমেয়াদী সমাধানের জন্য, অন্তর্নিহিত সমস্যাটি ঠিক করুন: লাইব্রেরিটিকে একটি SDK লাইব্রেরিতে রূপান্তর করুন, বা এর মডিউলের নাম পরিবর্তন করুন৷

  2. যদি পূর্ববর্তী ধাপটি একটি রেজোলিউশন প্রদান না করে, তাহলে প্রয়োজনীয় লাইব্রেরির জন্য uses_libs: ["<library-module-name>"] যোগ করুন, অথবা Android.bp এ ঐচ্ছিক লাইব্রেরির জন্য optional_uses_libs: ["<library-module-name>"] । মডিউলের Android.bp সংজ্ঞা। এই বৈশিষ্ট্যগুলি মডিউল নামের একটি তালিকা গ্রহণ করে। তালিকায় থাকা লাইব্রেরিগুলির আপেক্ষিক ক্রমটি ম্যানিফেস্টের ক্রমটির মতোই হতে হবে৷

Android.mk মডিউলগুলির জন্য:

  1. লাইব্রেরির মডিউল নাম (বিল্ড সিস্টেমে) থেকে আলাদা লাইব্রেরির নাম (মেনিফেস্টে) আছে কিনা তা পরীক্ষা করুন। যদি এটি হয়ে থাকে, লাইব্রেরির Android.mk ফাইলে LOCAL_PROVIDES_USES_LIBRARY := <library-name> যোগ করে সাময়িকভাবে এটি ঠিক করুন, অথবা লাইব্রেরির Android.bp ফাইলে provides_uses_lib: "<library-name>" যোগ করুন (উভয় ক্ষেত্রেই সম্ভব যেহেতু একটি Android.mk মডিউল একটি Android.bp লাইব্রেরির উপর নির্ভর করতে পারে)। দীর্ঘমেয়াদী সমাধানের জন্য, অন্তর্নিহিত সমস্যাটি ঠিক করুন: লাইব্রেরি মডিউলটির নাম পরিবর্তন করুন।

  2. প্রয়োজনীয় লাইব্রেরির জন্য LOCAL_USES_LIBRARIES := <library-module-name> যোগ করুন; মডিউলের Android.mk সংজ্ঞাতে ঐচ্ছিক লাইব্রেরির জন্য LOCAL_OPTIONAL_USES_LIBRARIES := <library-module-name> যোগ করুন। এই বৈশিষ্ট্যগুলি মডিউল নামের একটি তালিকা গ্রহণ করে। তালিকায় লাইব্রেরির আপেক্ষিক ক্রম ম্যানিফেস্টের মতোই হতে হবে।

বিল্ড ত্রুটি: অজানা লাইব্রেরি পথ

যদি বিল্ড সিস্টেম একটি <uses-library> DEX জার (হয় একটি বিল্ড-টাইম পাথ অন-হোস্ট বা একটি ইনস্টল পাথ অন-ডিভাইস), এটি সাধারণত বিল্ড ব্যর্থ হয়. একটি পথ খুঁজে পেতে ব্যর্থতা নির্দেশ করতে পারে যে লাইব্রেরিটি কিছু অপ্রত্যাশিত উপায়ে কনফিগার করা হয়েছে। সমস্যাযুক্ত মডিউলটির জন্য 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 তৈরি করে। এটি শীর্ষ-স্তরের CLC উপাদান হিসাবে মডিউলের ম্যানিফেস্টে <uses-library> ট্যাগে তালিকাভুক্ত লাইব্রেরিগুলিকে যুক্ত করে।

প্রতিটি ব্যবহৃত লাইব্রেরির জন্য, PackageManager তার সমস্ত <uses-library> নির্ভরতা পায় (সেই লাইব্রেরির ম্যানিফেস্টে ট্যাগ হিসাবে নির্দিষ্ট) এবং প্রতিটি নির্ভরতার জন্য একটি নেস্টেড CLC যোগ করে। এই প্রক্রিয়াটি পুনরাবৃত্তভাবে চলতে থাকে যতক্ষণ না নির্মাণ করা CLC গাছের সমস্ত লিফ নোড <uses-library> নির্ভরতা ছাড়াই লাইব্রেরি হয়।

PackageManager শুধুমাত্র শেয়ার করা লাইব্রেরি সম্পর্কে সচেতন। এই ব্যবহারে ভাগ করা সংজ্ঞাটি এর স্বাভাবিক অর্থ থেকে পৃথক (যেমন ভাগ করা বনাম স্ট্যাটিক)। অ্যান্ড্রয়েডে, জাভা শেয়ার করা লাইব্রেরিগুলি হল XML কনফিগারে তালিকাভুক্ত যেগুলি ডিভাইসে ইনস্টল করা আছে ( /system/etc/permissions/platform.xml )। প্রতিটি এন্ট্রিতে একটি শেয়ার্ড লাইব্রেরির নাম, এর DEX জার ফাইলের একটি পাথ এবং নির্ভরতার একটি তালিকা রয়েছে (অন্যান্য শেয়ার্ড লাইব্রেরি যা এটি রানটাইমে ব্যবহার করে এবং এর ম্যানিফেস্টে <uses-library> ট্যাগগুলিতে নির্দিষ্ট করে)।

অন্য কথায়, তথ্যের দুটি উৎস রয়েছে যা PackageManager রানটাইমে CLC তৈরি করতে দেয়: ম্যানিফেস্টে <uses-library> ট্যাগ, এবং XML কনফিগারেশনে শেয়ার করা লাইব্রেরি নির্ভরতা।

অন-হোস্ট (বিল্ড-টাইম) সিএলসি

CLC শুধুমাত্র একটি লাইব্রেরি বা একটি অ্যাপ লোড করার সময় প্রয়োজন হয় না, এটি একটি কম্পাইল করার সময়ও প্রয়োজন। কম্পাইলেশন হয় অন-ডিভাইস (ডেক্সপট) বা বিল্ডের সময় (ডেক্সপ্রিওপ্ট) ঘটতে পারে। যেহেতু dexopt ডিভাইসে সংঘটিত হয়, এতে PackageManager (প্রকাশিত এবং ভাগ করা লাইব্রেরি নির্ভরতা) হিসাবে একই তথ্য রয়েছে। Dexpreopt, তবে, হোস্টে এবং সম্পূর্ণ ভিন্ন পরিবেশে সঞ্চালিত হয় এবং এটিকে বিল্ড সিস্টেম থেকে একই তথ্য পেতে হবে।

এইভাবে, dexpreopt দ্বারা ব্যবহৃত বিল্ড-টাইম CLC এবং PackageManager দ্বারা ব্যবহৃত রান-টাইম CLC একই জিনিস, কিন্তু দুটি ভিন্ন উপায়ে গণনা করা হয়।

বিল্ড-টাইম এবং রান-টাইম সিএলসি অবশ্যই মিলে যাবে, অন্যথায় dexpreopt দ্বারা তৈরি AOT-সংকলিত কোড প্রত্যাখ্যান করা হবে। বিল্ড-টাইম এবং রান-টাইম CLC-এর সমতা পরীক্ষা করতে, dex2oat কম্পাইলার *.odex ফাইলে (OAT ফাইল হেডারের classpath ক্ষেত্রে) বিল্ড-টাইম CLC রেকর্ড করে। সঞ্চিত CLC খুঁজে পেতে, এই কমান্ডটি ব্যবহার করুন:

oatdump --oat-file=<FILE> | grep '^classpath = '

বুট করার সময় লগক্যাটে বিল্ড-টাইম এবং রান-টাইম CLC গরমিল রিপোর্ট করা হয়েছে। এই কমান্ড দিয়ে এটি অনুসন্ধান করুন:

logcat | grep -E 'ClassLoaderContext [az ]+ mismatch'

অসামঞ্জস্য কর্মক্ষমতার জন্য খারাপ, কারণ এটি লাইব্রেরি বা অ্যাপকে হয় dexopted হতে বাধ্য করে, অথবা অপটিমাইজেশন ছাড়াই চালাতে বাধ্য করে (উদাহরণস্বরূপ, অ্যাপের কোডটি APK থেকে মেমরিতে বের করতে হতে পারে, এটি একটি অত্যন্ত ব্যয়বহুল অপারেশন)।

একটি ভাগ করা লাইব্রেরি ঐচ্ছিক বা প্রয়োজনীয় হতে পারে। dexpreopt দৃষ্টিকোণ থেকে, একটি প্রয়োজনীয় লাইব্রেরি নির্মাণের সময় উপস্থিত থাকতে হবে (এর অনুপস্থিতি একটি বিল্ড ত্রুটি)। একটি ঐচ্ছিক লাইব্রেরি নির্মাণের সময় উপস্থিত বা অনুপস্থিত হতে পারে: যদি উপস্থিত থাকে, তাহলে এটি CLC-তে যোগ করা হয়, dex2oat-এ পাস করা হয় এবং *.odex ফাইলে রেকর্ড করা হয়। যদি একটি ঐচ্ছিক লাইব্রেরি অনুপস্থিত থাকে, এটি এড়িয়ে যাওয়া হয় এবং CLC এ যোগ করা হয় না। যদি বিল্ড-টাইম এবং রান-টাইম স্ট্যাটাসের মধ্যে অমিল থাকে (একটি ক্ষেত্রে ঐচ্ছিক লাইব্রেরি উপস্থিত থাকে, কিন্তু অন্য ক্ষেত্রে নয়), তাহলে বিল্ড-টাইম এবং রান-টাইম CLC মেলে না এবং কম্পাইল করা কোড প্রত্যাখ্যান করা হয়।

উন্নত বিল্ড সিস্টেমের বিশদ বিবরণ (মেনিফেস্ট ফিক্সার)

কখনও কখনও <uses-library> ট্যাগগুলি একটি লাইব্রেরি বা অ্যাপের সোর্স ম্যানিফেস্ট থেকে অনুপস্থিত থাকে। এটি ঘটতে পারে, উদাহরণস্বরূপ, যদি লাইব্রেরি বা অ্যাপের একটি ট্রানজিটিভ নির্ভরতা অন্য একটি <uses-library> ট্যাগ ব্যবহার করা শুরু করে এবং এটি অন্তর্ভুক্ত করার জন্য লাইব্রেরি বা অ্যাপের ম্যানিফেস্ট আপডেট করা না হয়।

Soong একটি প্রদত্ত লাইব্রেরি বা অ্যাপের জন্য কিছু অনুপস্থিত <uses-library> ট্যাগ স্বয়ংক্রিয়ভাবে গণনা করতে পারে, যেমন SDK লাইব্রেরি লাইব্রেরি বা অ্যাপের ট্রানজিটিভ নির্ভরতা বন্ধে। বন্ধ করা প্রয়োজন কারণ লাইব্রেরি (বা অ্যাপ) একটি স্ট্যাটিক লাইব্রেরির উপর নির্ভর করতে পারে যা একটি SDK লাইব্রেরির উপর নির্ভর করে এবং সম্ভবত আবার অন্য লাইব্রেরির মাধ্যমে ট্রানজিটিভভাবে নির্ভর করতে পারে।

সমস্ত <uses-library> ট্যাগ এইভাবে গণনা করা যায় না, কিন্তু যখন সম্ভব, Soong কে স্বয়ংক্রিয়ভাবে ম্যানিফেস্ট এন্ট্রি যোগ করতে দেওয়া বাঞ্ছনীয়; এটি কম ত্রুটি-প্রবণ এবং রক্ষণাবেক্ষণকে সহজ করে। উদাহরণস্বরূপ, যখন অনেক অ্যাপ একটি স্ট্যাটিক লাইব্রেরি ব্যবহার করে যা একটি নতুন <uses-library> নির্ভরতা যোগ করে, তখন সমস্ত অ্যাপ আপডেট করতে হবে, যা বজায় রাখা কঠিন।