Android প্ল্যাটফর্ম বিল্ড সিস্টেম (Soong) R8 কম্পাইলারকে
সেইসব টার্গেটে রান করায় যেগুলি Android অ্যাপ (android_app), টেস্ট
(android_test) এবং compile_dex: true (যেমন
services.jar) সহ ইনস্টল করা যায় এমন Java লাইব্রেরি সহ DEX বাইটকোড কম্পাইল করে। এর ফলে, অব্যবহৃত কোড ও রিসোর্স ছোট, অপ্টিমাইজ ও স্ট্রিপ করা যায়। স্ট্যাটিক লাইব্রেরিতে (android_library এবং স্ট্যাটিক java_library), Soong সরাসরি
R8 রান করে না, তবে optimize প্রপার্টি ব্লক ব্যবহার করে
ডাউনস্ট্রিম DEX টার্গেটে (export_proguard_flags_files: true) কনজিউমার কিপ রুল অ্যাটাচ ও প্রোপাগেট করে
যেগুলি স্ট্যাটিক লিঙ্ক করে।
সিস্টেম ইমেজ বা ভেন্ডর প্যাকেজ তৈরি করা প্ল্যাটফর্ম ইঞ্জিনিয়ারদের জন্য, অতিরিক্ত ব্যাপক 'কীপ' সংক্রান্ত নিয়ম বাদ দিলে সরাসরি সিস্টেমের স্বাস্থ্যের ব্যাপারে সুবিধা পাওয়া যায়:
- ছোট সিস্টেম পার্টিশন ফুটপ্রিন্ট: R8,
/system,/system_ext,/productএবং/vendor-এ APK ও JAR প্যাকেজ করার আগে ডেড ক্লাস, মেথড ও রিসোর্স সরিয়ে দেয়। - কম্পাইল করা ছোট আর্টিফ্যাক্ট: কম DEX মেথড মানে
dex2oat-এর দ্বারা বিল্ড-টাইম বা অন-ডিভাইস কম্পাইলেশনের সময় তৈরি হওয়া ছোট.odexএবং.vdexফাইল। - কম রানটাইম মেমরি প্রেসার: কারণ Android,
.odex,.vdex, এবং APK রিসোর্স টেবিলকে ডিমান্ড-পেজডmmapকলের মাধ্যমে প্রসেস মেমরিতে ম্যাপ করে, ছোট বাইনারি অ্যাপ স্টার্ট-আপের সময় মেজর পেজ ফল্ট কমিয়ে দেয় এবং প্রসেস জুড়ে রেসিডেন্ট কোড এবং রিসোর্স মেমরি কমিয়ে দেয়। কম্পাইল করা অ্যাপ কোড কীভাবে ডিভাইসের মেমরিকে প্রভাবিত করে সেই সম্পর্কে আরও জানতে, অ্যাপ কোড হল মেমরি লিঙ্ক দেখুন। - আরও কার্যকর সম্পূর্ণ-প্রোগ্রাম অপ্টিমাইজেশন: সংকীর্ণ কিপ কনস্ট্রেন্ট R8 ইনলাইন পদ্ধতি, ডিভার্চুয়ালাইজ ইন্টারফেস ও ভার্চুয়াল কল, অব্যবহৃত ফিল্ড বাদ দেওয়া এবং ক্লাস জুড়ে কনস্ট্যান্ট প্রোপাগেট করার অনুমতি দেয়।
Soong-এ R8 অপ্টিমাইজেশন কনফিগার করা
Android.bp ফাইলে, optimize প্রপার্টি ব্যবহার করে R8 অপ্টিমাইজেশন কনফিগার করুন
android_app এবং ইনস্টল করা যায় এমন java_library টার্গেট (অথবা
android_library এবং স্ট্যাটিক java_library মডিউল যাতে কনজিউমার কিপ
নিয়ম এক্সপোর্ট করা যায়):
android_app {
name: "MySystemApp",
srcs: ["src/**/*.java"],
optimize: {
obfuscate: true,
shrink_resources: true,
},
}
নিচের সারণীতে Soong-এর সবচেয়ে সাধারণ optimize প্রপার্টিগুলির সারসংক্ষেপ দেওয়া হল
(build/soong/java/dex.go-এ সংজ্ঞায়িত):
| প্রপার্টি | বর্ণনা |
|---|---|
enabled |
টার্গেটে R8 রান করবে কিনা তা কন্ট্রোল করে। সব android_app টার্গেটের জন্য ডিফল্ট হিসেবে true
সেট করা থাকে।
|
shrink |
অপ্রাপ্য ক্লাস, ফিল্ড ও
মেথড সরিয়ে দিতে ট্রি শেকিং কন্ট্রোল করে। android_app
টার্গেটের জন্য ডিফল্ট হিসেবে true (স্ট্যান্ডঅ্যালোন java_library ও
টেস্ট মডিউলের জন্য false, যা স্পষ্টভাবে
সেট করা না থাকলে -dontshrink পাস করে)।
|
optimize |
মেথড ইনলাইনিং, ক্লাস মার্জিং,
কনস্ট্যান্ট প্রোপাগেশন ও ডেড ব্রাঞ্চ রিমুভালের মতো বাইটকোড অপ্টিমাইজেশন কন্ট্রোল করে। android_app টার্গেটের জন্য ডিফল্ট হিসেবে
true (RELEASE_R8_OPTIMIZE_BY_DEFAULT রিলিজ বিল্ড ফ্ল্যাগ দ্বারা
নিয়ন্ত্রিত) সেট করা থাকে।
|
obfuscate |
শনাক্তকারী ছোট করা ও নাম পরিবর্তন করা নিয়ন্ত্রণ করে। ডিফল্ট হিসেবে
false থাকে, তবে DEX সাইজ কমানো এবং
আরও গভীর অপ্টিমাইজেশন আনলক করার জন্য যেখানেই সম্ভব
true হিসেবে সেট করুন (দেখুন
যেখানে সম্ভব সেখানে অবফাসকেশন চালু করুন)।
|
shrink_resources |
কোড ছোট করার পরে প্যাকেজ করা APK থেকে অব্যবহৃত রিসোর্স (res/ এন্ট্রি) সরিয়ে দেয়।
ডিফল্ট হিসেবে false সেট করা থাকে।
|
optimized_shrink_resources |
ইন্টিগ্রেটেড R8 কোড ও রিসোর্স শ্রিন্কার পাইপলাইন রান করে, যাতে R8 ট্রেস
কোড ও রিসোর্স রেফারেন্স একসাথে একটি সিঙ্গেল পাসে করা যায়। shrink_resources: true সেট করা থাকলে, RELEASE_USE_OPTIMIZED_RESOURCE_SHRINKING_BY_DEFAULT
(সাধারণ প্ল্যাটফর্ম বিল্ডে true) ডিফল্ট হিসেবে
সেট হয়ে যায়।
|
proguard_flags_files |
কাস্টম কীপ সংক্রান্ত নিয়মাবলী সহ তালিকা মডিউল-নির্দিষ্ট .flags বা .pro ফাইল
। স্ট্যান্ডার্ড
অ্যানোটেশন বা ডিফল্ট মান যথেষ্ট হলে কাস্টম ফাইল যোগ করা এড়িয়ে চলুন।
|
export_proguard_flags_files |
এই লাইব্রেরির proguard_flags_files, এর উপর স্ট্যাটিকভাবে নির্ভর করে এমন
ডাউনস্ট্রিম মডিউলে প্রোপাগেট করে।
|
trace_references_from |
এই টার্গেটে বাইটের কোড রেফারেন্স সহ Java লাইব্রেরি কম্প্যানিয়ন টার্গেট তালিকাভুক্ত করে। R8 অটোমেটিক ট্রেস করে এবং রেখে দেয়। |
যেখানে সম্ভব সেখানে অবফাসকেশন চালু করুন
Soong-এ, obfuscate ঐতিহাসিক কম্প্যাটিবিলিটির জন্য false ডিফল্ট হিসেবে সেট করা থাকে, কিন্তু আপনি
সম্ভব হলে android_app এবং স্বতন্ত্র DEX
টার্গেটে obfuscate: true স্পষ্টভাবে সেট করুন:
- ছোট DEX ও
.vdexফুটপ্রিন্ট: প্যাকেজ, ক্লাস, ফিল্ডের নাম পরিবর্তন করে ছোট শনাক্তকারী (a,b) ব্যবহার করলে DEX স্ট্রিং পুল (string_idsওstring_data_item) ও টাইপ ডেসক্রিপ্টর ছোট হয়ে যায়। কারণ Android প্রসেস মেমরিতে.vdexও.odexফাইল ম্যাপ করে, ছোট সিম্বল টেবিল সিস্টেম পার্টিশনের সাইজ ও রানটাইম মেমরি ফুটপ্রিন্ট, দুটিই সরাসরি কমিয়ে দেয়। - আরও গভীর লেভেলে সম্পূর্ণ প্রোগ্রাম অপ্টিমাইজ করা: R8-কে শনাক্তকারী রিনেম করতে দিলে ক্লাস মার্জ করা, প্যাকেজ ফ্ল্যাট করা এবং সিন্থেটিক ক্লাস ডিডুপ্লিকেট করা আনলক হয়ে যায়। R8-কে নামের সংঘর্ষ এড়ানোর জন্য অন্যথায় এগুলি এড়িয়ে যেতে হত।
- সম্পূর্ণ স্ট্যাক ট্রেস সিম্বোলাইজেশন: Soong-এ অবফাসকেশন চালু করলে
ডিবাগ করার ক্ষমতা কমে যায় না। R8-কম্পাইল করা প্রতিটি টার্গেটের জন্য, Soong মডিউলের ইন্টারমিডিয়েট ডিরেক্টরিতে একটি
proguard_dictionaryম্যাপিং ফাইল তৈরি করে, বিল্ডেরproguard-dict.zipআর্টিফ্যাক্টে সমস্ত মডিউল ডিকশনারি বান্ডেল করে, DEX হেডার মধ্যে একটি ম্যাপিং হ্যাশ (--map-id-template) এম্বেড করে, এবং ক্লাসSourceFileঅ্যাট্রিবিউট (--source-file-template) আবার লেখে যাতেretraceঅটোমেটিক স্ট্যাক ট্রেস সিম্বোলাইজ করতে পারে।
শুধুমাত্র এগুলির জন্য obfuscate: false (বা স্পষ্টভাবে পাবলিক API নাম সংরক্ষণ করুন) ব্যবহার করুন:
- bootclasspath বা
system_serverclasspath-এ শেয়ার করা লাইব্রেরি: মডিউল (java_libraryবাjava_sdk_library) যা এক্সটার্নাল API প্রকাশ করে রানটাইমে অন্যান্য মডিউল দ্বারা ডাইনামিক লিঙ্ক করা সারফেস (যেমনframework.jar,services.jarবা<uses-library>টার্গেট) অবশ্যইobfuscate: falseরাখতে হবে অথবা@KeepForApiবা-keepনিয়মের (bootclasspath টার্গেটের জন্যprotect_api_surface: trueসহ) মাধ্যমে স্পষ্টভাবে তাদের API সারফেস প্রিজার্ভ করতে হবে, যাতে তাদের স্টাবের বিরুদ্ধে কম্পাইল করা কলাররা রানটাইমে ক্লাস ও মেম্বার নাম সমাধান করতে পারে।
কোনও অ্যাপ্লিকেশনে obfuscate: true চালু করার আগে, নিম্নলিখিত
মাইগ্রেশন পূর্বশর্তগুলি যাচাই করুন:
- এক্সটার্নাল টেস্ট APK-এর উপর নির্ভরতা: কোনও এক্সটার্নাল
android_testAPK সেটinstrumentation_for: "MyApp"এবং সরাসরি ইন্টার্নাল ক্লাস বাMyApp-এর মেথড ইনভোক করলে, সেইসব প্রতীকগুলির নাম পরিবর্তন করলে টেস্ট রানটাইমেNoSuchMethodErrorবাNoClassDefFoundErrorহয়। টেস্টকে এমনভাবে স্ট্রাকচার করুন যাতে সেটি সেল্ফ-ইনস্ট্রুমেন্টিং APK-এর সাথেMyApp.implস্ট্যাটিক্যালি লিঙ্ক করা থাকে,@VisibleForTestingদিয়ে টেস্ট হুক অ্যানোটেট করা থাকে অথবাtrace_references_fromকনফিগার করা থাকে (ধাপ ২: টেস্ট-ড্রিভেন কীপ নিয়ম মাইগ্রেট করুন দেখুন), যাতে অ্যাপের বাকি অংশ অবফিউস্কেট করার সময় টেস্টের জন্য প্রয়োজনীয় ইন্টার্নাল সিম্বল সংরক্ষিত থাকে। - স্ট্রিং-ভিত্তিক রিফ্লেকশন ও JNI: কোনও মডিউল যদি কিপ নিয়ম বা অ্যানোটেশন ছাড়াই, আক্ষরিক স্ট্রিং নামের (
Class.forName,getDeclaredMethodবা JNIFindClassওGetMethodID) মাধ্যমে ক্লাস, মেথড, বা ফিল্ড খুঁজে দেখে, তাহলে অবফাসকেশন সেইসব টার্গেটকে রিনেম করে এবং রানটাইম লুক-আপ ভেঙে দেয়। (মনে রাখবেন যে অ্যানোটেশন না করা রিফ্লেকশনওshrink: trueওoptimize: true-এর অধীনে পড়ে।) সেইসব এন্ট্রি পয়েন্টে অ্যানোটেশন বজায় রাখার গাইড (@UsesReflection,@UsedByReflectionবা@UsedByNative) যোগ করুন যাতে R8 তাদের নাম বজায় রাখতে পারে এবং বাকি মডিউল অস্পষ্ট করতে পারে।
জিরো কাস্টম ফ্ল্যাগ নীতি অনুসরণ করা
আদর্শ Android প্ল্যাটফর্ম মডিউলে কোনও কাস্টম proguard.flags বা keep.xml
ফাইল নেই। Android প্ল্যাটফর্ম বিল্ডে, কাস্টম কিপ সংক্রান্ত নিয়মের বেশিরভাগই
অপ্রয়োজনীয়:
- প্ল্যাটফর্ম বেসলাইন ও AAPT2: বেশিরভাগ এন্ট্রি পয়েন্ট ইতিমধ্যেই গ্লোবাল প্ল্যাটফর্ম বেসলাইন (যেমন
@Keep, JNInativeমেথড ও@VisibleForTesting) দ্বারা অটোমেটিক রিটেন করা হয় অথবা AAPT2 থেকেAndroidManifest.xmlও লেআউট রিসোর্স (দেখুন ডিফল্ট প্ল্যাটফর্ম কিপ সংক্রান্ত নিয়ম বুঝুন) দ্বারা জেনারেট করা হয়। - টার্গেট করা বিকল্প: যেখানে এন্ট্রি পয়েন্ট অবশ্যই সুরক্ষিত রাখতে হবে, সেখানে
ঘোষণা-সাইট সংক্রান্ত অ্যানোটেশন (
keepanno,@VisibleForTesting), এক্সপোর্ট করা লাইব্রেরি নিয়ম (export_proguard_flags_files: true) অথবা আলাদা করা.flagsফাইলের উপর স্ট্যাটিক টেস্ট লিঙ্কিং (দেখুন আগেকার 'কিপ' নিয়ম অডিট ও মাইগ্রেট করা) ব্যবহার করুন।
কাস্টম proguard.flags বা keep.xml ফাইল যোগ বা রেখে দেওয়ার আগে, যাচাই করে নিন যে
নিয়মটি আগে থেকেই ডিফল্ট বেসলাইন দ্বারা ম্যানেজ করা হয় কিনা অথবা কোড
অ্যানোটেশনে মাইগ্রেট করা যায় কিনা।
ডিফল্ট প্ল্যাটফর্মের ডেটা রাখার নিয়ম সম্পর্কে জানুন
build/soong/java/dex.go-এ কনফিগার করা DEX-কম্পাইলিং টার্গেটে (android_app, android_test এবং
ইনস্টল করা যায় এমন java_library মডিউল) প্রতিটি R8
ইনভোকেশনে Soong অটোমেটিক নিম্নলিখিত গ্লোবাল বেসলাইন নিয়ম পাস করে:
build/make/core/proguard.flags:@com.android.internal.annotations.VisibleForTestingদিয়ে অ্যানোটেট করা ক্লাস ও মেম্বারদের সব প্যাকেজ জুড়ে এবং@VisibleForTestingদিয়ে (androidx.annotation.VisibleForTestingবাcom.google.common.annotations.VisibleForTesting)android.**,com.android.**ওcom.google.android.**প্যাকেজের মধ্যে সংরক্ষণ করে। এছাড়াও, এটি@TestApi,@Keep(androidx.annotation,android.support.annotation,com.android.internal.annotations),@KeepForWeakReference,@WeaklyReferencedCallbackএবং@dalvik.annotation.optimization.**অক্ষুণ্ণ রাখে।build/make/core/proguard_basic_keeps.flags: স্ট্যাক ট্রেস, রানটাইম ভিজিবিলিটি অ্যানোটেশন (RuntimeVisible*Annotations),ExceptionsএবংAnnotationDefaultঅ্যাট্রিবিউট,nativeপদ্ধতি,Serializableমেম্বার,@JavascriptInterfaceপদ্ধতি,Throwable(String)কনস্ট্রাক্টর,Parcelable$CREATORফিল্ড এবং protobufMessageLiteফিল্ডেরSourceFileঅ্যাট্রিবিউট বজায় রাখে।build/make/core/proguard/kotlin.flags: নির্দিষ্ট Kotlin মেটা-অ্যানোটেশনের (kotlin.Metadataএবংkotlin.annotation.{AnnotationRetention,AnnotationTarget,Retention,Target}) জন্য ক্ষতিকর নয় এমন সতর্কতা সাইলেন্স করে এবং রিলিজ বিল্ডে KotlinDebugMetadataঅ্যানোটেশন সরিয়ে দেয়।build/make/core/proguard/checknotnull.flags: সাধারণ নাল চেক হেল্পার কল (com.google.common.base.Preconditions.checkNotNullওdagger.internal.Preconditions.checkNotNull*)-এর পরিবর্তে সংক্ষিপ্ত বাইটকোড নাল চেক ব্যবহার করে। ফ্রেমওয়ার্ক API সীমানা জুড়ে স্পষ্ট ব্যতিক্রম মেসেজ সংরক্ষণ করতে এই ফাইলটি ইচ্ছাকৃতভাবেObjects.requireNonNullবাদ দেয়।build/make/core/proguard/enumvalues.flags: বিল্ড কনফিগারেশন দ্বারা বন্ধ না করা পর্যন্তenumধরনের উপরvaluesএবংvalueOfপদ্ধতি বজায় রাখে।- AAPT2 অটোমেটিক তৈরি করা নিয়ম: AAPT2 মার্জ করা
AndroidManifest.xml, লেআউট XML এবং পছন্দ XML ফাইল পরীক্ষা করে প্রতিটি রেজিস্টার করাActivity,Service,BroadcastReceiver,ContentProvider,BackupAgent,Application, কাস্টমViewসাবক্লাস,Preferenceসাবক্লাস, এবং XMLandroid:onClickপদ্ধতির জন্য সঠিক কিপ নিয়ম তৈরি করে।
আগে থেকে থাকা কীপ সংক্রান্ত নিয়ম অডিট ও মাইগ্রেট করা
কোনও প্ল্যাটফর্ম
রেপোজিটরিতে আগে থেকে থাকা proguard.flags বা keep.xml ফাইল অডিট করার সময়, নিম্নলিখিত চার-ধাপের
ক্রম অনুসারে প্রতিটি নিয়ম মূল্যায়ন করুন:
ধাপ ১: অপ্রয়োজনীয় বা পুরনো নিয়ম মুছে দিন
গ্লোবাল বেসলাইন, AAPT2 ম্যানিফেস্ট এবং লেআউট নিয়ম বা R8 ডিফল্ট দ্বারা ইতিমধ্যেই কভার করা নিয়ম এবং আর নেই এমন ক্লাস বা প্যাকেজকে রেফার করা নিয়ম মুছে দিন।
.flags ফাইলে থাকা সব নিয়ম অপ্রয়োজনীয় হলে, ফাইলটি মুছে দিন এবং Android.bp থেকে
proguard_flags_files সরিয়ে দিন। অবশিষ্ট optimize ব্লকে শুধুমাত্র
ডিফল্ট সেটিংসের পুনরাবৃত্তি করা হলে, অপ্রয়োজনীয় ব্লক সরিয়ে দিন এবং bpfmt -w Android.bp ব্যবহার করে
বিল্ড ফাইল ফর্ম্যাট করুন। কোনও প্যাকেজ পরিষ্কার করার সময়, চেক করে দেখুন যে সাবডিরেক্টরিতে (যেমন, Kotlin টার্গেট ভ্যারিয়েন্ট) থাকা কম্প্যানিয়ন
মডিউল একই
ফ্ল্যাগ ফাইলকে রেফার করছে কিনা এবং সেগুলি একসাথে আপডেট করুন।
ধাপ ২: টেস্ট-ড্রিভেন কীপ নিয়ম মাইগ্রেট করা
নিম্নলিখিত প্যাটার্নের মধ্যে একটি ব্যবহার করে কাস্টম প্রোডাকশন .flags ফাইল থেকে টেস্ট-ড্রাইভেন কিপ নিয়ম সরান:
টেস্টে ইমপ্লিমেন্টেশন লাইব্রেরি লিঙ্ক করুন (
static_libs): কোনওandroid_testঅ্যাপের প্যাকেজ-প্রাইভেট বা ইন্টার্নাল ইমপ্লিমেন্টেশন ডিটেলেইলের ব্যবহার করলে, সাজেস্ট করা প্ল্যাটফর্ম আর্কিটেকচার হল অ্যাপ সোর্স ফাইলকেandroid_library(MyApp.impl) ফোল্ডারে রাখা এবংMyAppওMyAppTestsMyApp.implদুটিতেই স্ট্যাটিক লিঙ্ক করা:android_library { name: "MyApp.impl", srcs: ["src/**/*.java"], manifest: "AndroidManifest.xml", } android_app { name: "MyApp", static_libs: ["MyApp.impl"], optimize: { obfuscate: true, shrink_resources: true, }, } android_test { name: "MyAppTests", srcs: ["tests/**/*.java"], static_libs: ["MyApp.impl"], }এই ৩-মডিউল প্যাটার্ন
MyAppTestsইন্টার্নাল ক্লাসে সম্পূর্ণ অ্যাক্সেস সহ সেল্ফ-ইনস্ট্রুমেন্টিং টেস্ট হিসেবে রান করতে দেয়,MyAppটেস্ট ভেঙে না দিয়েobfuscate: trueফ্রিলি চালু করতে দেয়, প্রোডাকশন APK-তে শুধুমাত্র টেস্ট-অনলি এন্ট্রি পয়েন্ট শিপ করা এড়ায় এবং টেস্ট কোড পরিবর্তন হলেMyAppআবার বিল্ড করার প্রয়োজন হয় না।@VisibleForTestingদিয়ে টেস্ট হুক অ্যানোটেট করুন: কোনও এক্সটার্নাল টেস্ট APK যদিandroid_appটার্গেটে অল্প সংখ্যক ইন্টার্নাল মেথড বা কনস্ট্রাক্টর কল করে এবং.implলাইব্রেরিতে পুনর্গঠন করা অবাস্তব হয়, তাহলে@VisibleForTestingদিয়ে সেইসব ঘোষণা অ্যানোটেট করুন। কাস্টম.flagsফাইল ছাড়াই গ্লোবালbuild/make/core/proguard.flagsবেসলাইন@VisibleForTestingandroid.**,com.android.**ওcom.google.android.**প্যাকেজে আইটেম অটোমেটিক রেখে দেয়। (এইসব নেমস্পেসের বাইরের ভেন্ডর মডিউলের জন্য,@UsedByReflectionবা এক্সপোর্ট করা লাইব্রেরি রুল ব্যবহার করুন।)প্ল্যাটফর্ম লাইব্রেরি সীমানা জুড়ে
trace_references_fromব্যবহার করুন: যখন টেস্ট টার্গেট ইমপ্লিমেন্টেশনকে স্ট্যাটিক লিঙ্ক করতে পারে না (যেমন, সিস্টেম সার্ভার পরিষেবা বাframework-connectivity-এর মতো প্ল্যাটফর্ম JAR-কে এক্সারসাইজ করা টেস্ট), তখন টার্গেট মডিউলেtrace_references_fromকনফিগার করুন যা টেস্ট সোর্স থাকা Java লাইব্রেরি কম্প্যানিয়ন মডিউলের দিকে পয়েন্ট করে। R8, কম্প্যানিয়ন বাইটকোড দ্বারা রেফারেন্স করা সব ক্লাস ও মেম্বারকে ট্রেস ও রিটেন করে।
ধাপ ৩: মালিকানাধীন লাইব্রেরি থেকে নিয়ম এক্সপোর্ট করা
শেয়ার করা java_library বা android_library-এর নিজস্ব ইন্টার্নাল রিফ্লেকশন বা JNI কলব্যাকের জন্য
কীপ রুল প্রয়োজন হলে, লাইব্রেরি টার্গেটে নিয়মগুলি ডিফাইন করুন এবং
export_proguard_flags_files: true সেট করুন:
java_library {
name: "my-shared-library",
srcs: ["src/**/*.java"],
optimize: {
proguard_flags_files: ["proguard.flags"],
export_proguard_flags_files: true,
},
}
স্ট্যাটিক লিঙ্ক করা
my-shared-library সব ডাউনস্ট্রিম android_app এবং লাইব্রেরি টার্গেট অটোমেটিক সেইসব নিয়ম ইনহেরিট করে, তাই ডাউনস্ট্রিম অ্যাপকে
সেগুলি ডুপ্লিকেট করতে হয় না। বিভিন্ন ডিরেক্টরি জুড়ে একাধিক মডিউলকে যদি এমন একটি নিয়মের সেট শেয়ার করতে হয় যা কোনও একটি কোড লাইব্রেরির সাথে যুক্ত নয়, তাহলে Android.bp-এ একটি এক্সপ্লিসিট filegroup-এর মাধ্যমে .flags
ফাইল প্রকাশ করুন, যাতে মডিউলগুলি প্যাকেজ বাউন্ডারি জুড়ে
:my-shared-flags পরিষ্কারভাবে রেফারেন্স করতে পারে। ডাউনস্ট্রিম অ্যাপ
অপ্টিমাইজেশন সীমাবদ্ধ না করে লাইব্রেরি কনজিউমার কিপ রুল
লেখার বিষয়ে সাধারণ নির্দেশিকা পেতে, লাইব্রেরি লেখকদের জন্য অপ্টিমাইজেশন দেখুন।
ধাপ ৪: সোর্স কোডে ঘোষণাগুলি অ্যানোটেট করা
কোনও ক্লাস, মেথড, কনস্ট্রাক্টর বা ফিল্ড রিফ্লেকশন বা
JNI-এর মাধ্যমে অ্যাক্সেস করা হলে এবং AAPT2 বা গ্লোবাল বেসলাইন দ্বারা কভার করা না হলে, -keep
.flags ফাইলে বিচ্ছিন্ন নিয়মগুলিকে
অ্যানোটেশন রাখার গাইড থেকে সোর্স অ্যানোটেশন দিয়ে পরিবর্তন করুন (দেখুন
keepanno Javadoc রেফারেন্স):
@UsesReflection: আপনি যখন রিফ্লেকশন পারফর্ম করা কোড কন্ট্রোল করেন, তখন এই অ্যানোটেশন ব্যবহার করুন। কোন টার্গেট ক্লাস, পদ্ধতি বা ফিল্ড ডায়নামিক অ্যাক্সেস করা হয় তা ঘোষণা করতে রিফ্লেকশন কলের সাইটে এটি রাখুন। কারণ,@UsesReflectionঅটোমেটিক একটি পূর্বশর্ত এনকোড করে যে অ্যানোটেটেড কল সাইটটি নিজেই অ্যাক্সেস করা যায়। কল সাইটটি ব্যবহার করা না হলে, R8 কলকারী ও রিফ্লেক্টিভ টার্গেট, দুটিকেই বাদ দেয়।@UsedByReflection: ক্লাস, মেথড, ফিল্ড বা কনস্ট্রাক্টর যাClass.forNameথেকে লোড করা ক্লাসBundleবাSettingsকী অথবা ডায়নামিক ক্লাসলোডার জুড়ে লোড করা প্লাগ-ইন ক্লাসের মতো এক্সটার্নাল কোড বা লাইব্রেরি দ্বারা ইনস্ট্যানশিয়েট বা রিফ্লেক্টিভলি ইনভোক করা হয়, সেগুলিতে প্লেস করুন।kind(যেমনKeepItemKind.CLASS_AND_METHODS),preconditions(@KeepCondition) এবং প্যারামিটার সীমাবদ্ধতা নির্দিষ্ট করুন যাতে R8 শুধুমাত্র সঠিক রিফ্লেক্টিভ কন্ট্র্যাক্ট রাখে এবং এখনও ক্লাসের অব্যবহৃত মেম্বারদের অপ্টিমাইজ বা বাদ দিতে পারে।JobServiceবাBroadcastReceiver-এর মতো ম্যানিফেস্ট-রেজিস্টার্ড কম্পোনেন্টে@UsedByReflectionযোগ করবেন না, কারণ AAPT2 আগেই এগুলি রেখে দেয়।@UsedByNative: C বা C++ JNI কোড থেকেGetMethodID,GetStaticMethodIDবাGetFieldIDব্যবহার করে অ্যাক্সেস করা পদ্ধতি বা ফিল্ডে প্লেস করুন।@KeepForApi: লাইব্রেরি API ক্লাস বা মেম্বারদের এমন জায়গায় রাখুন যেগুলি ডিস্ট্রিবিউশনের আগে লাইব্রেরি ছোট করার সময় অবিকৃত রাখতে হবে।@Keep(androidx.annotation.Keep):keepannoপ্রযোজ্য না হলে ফলব্যাক হিসেবে ব্যবহার করুন। কোনও ক্লাসে@Keepপ্রয়োগ করলে, ক্লাস ও এর সব সদস্যকে শর্তহীনভাবে রেখে দেওয়া হয়। কোনও মেথড বা ফিল্ডে@Keepপ্রয়োগ করলে তা আনকন্ডিশনাল এন্ট্রি পয়েন্ট হিসেবে কাজ করে যা মেম্বার ও তার কন্টেনিং ক্লাসকে ধরে রাখে, এমনকি ক্লাস কখনও ইনস্ট্যানশিয়েট না হলেও। অন্যদিকে,keepannoকন্ডিশনাল রিচেবিলিটি প্রকাশ করে।
Soong মডিউলে R8 keepanno অ্যানোটেশন ব্যবহার করতে:
Android.bp-এlibs-এ"keepanno-annotations"যোগ করুন:libs: [ "keepanno-annotations", ],Java বা Kotlin সোর্স কোডে
com.android.tools.r8.keepanno.annotations.*ইমপোর্ট করুন এবং ঘোষণা বা কল সাইটকে অ্যানোটেট করুন:import com.android.tools.r8.keepanno.annotations.KeepItemKind; import com.android.tools.r8.keepanno.annotations.UsedByReflection; public final class CustomPluginController { @UsedByReflection( description = "Instantiated via Class.forName from plugin config", kind = KeepItemKind.CLASS_AND_METHODS) public CustomPluginController(Context context) { // ... } }R8
keepannoঅ্যানোটেশনকে সরাসরি এর ইন্টার্নাল কিপ রুল মডেলে ট্রান্সলেট করে এবং ফাইনাল DEX আউটপুট থেকে অ্যানোটেশন সরিয়ে দেয়, এর ফলে রানটাইম বাইটকোড ওভারহেড শূন্য হয়ে যায়।
সাধারণ ভুলগুলি এড়িয়ে চলুন
নিচের বিভাগে প্ল্যাটফর্ম কোডে প্রায়ই হওয়া proguard.flags এবং keep.xml
ভুল ও সেগুলি কীভাবে সমাধান করতে হয় তা বর্ণনা করা হয়েছে।
ব্রড কম্পোনেন্ট কীপ সংক্রান্ত নিয়ম
# Don't do this:
-keep class * extends android.app.Activity
-keep class * extends android.app.Service
-keep class * extends android.content.BroadcastReceiver
- এটি কেন পারফর্ম্যান্সের উপর প্রভাব ফেলে: এই নিয়মটি AAPT2-এর সাথে সম্পূর্ণভাবে অপ্রয়োজনীয়।
কারণ, এটি ওয়াইল্ডকার্ড ব্যবহার করে, তবে ফাইনাল মার্জ করা
AndroidManifest.xml-এ কম্পোনেন্ট রেজিস্টার করা আছে কিনা তা চেক করে না। এর ফলে R8-কে প্রতিটিActivity,ServiceবাBroadcastReceiverসাবক্লাস ধরে রাখতে বাধ্য করে, যা classpath-এ কোথাও না কোথাও পাওয়া যায়। এর মধ্যে অব্যবহৃত লাইব্রেরি কম্পোনেন্ট ও ডিবাগ অ্যাক্টিভিটি অন্তর্ভুক্ত থাকে। - সাজেস্ট করা সমাধান: নিয়মটি মুছে দিন। AAPT2 মার্জ করা ম্যানিফেস্ট পরিদর্শন করে এবং
রেজিস্টার করা কম্পোনেন্টের জন্য হুবহু
-keepনিয়ম তৈরি করে।
XML ক্লিক হ্যান্ডলারের নিয়ম বজায় রাখা
# Don't do this:
-keepclassmembers class * {
public void *(android.view.View);
}
- পারফর্ম্যান্সের উপর এর প্রভাব: মডিউলের প্রতিটি ক্লাসে প্রতিটি
public void *(View)পদ্ধতি রিটেন করা হলে, R8 কোনও পদ্ধতি স্ট্রিপ বা ইনলাইন করতে পারে না যা একটিViewপ্যারামিটার গ্রহণ করে। - সাজেস্ট করা সমাধান: নিয়মটি মুছে দিন। AAPT2 লেআউট XML ফাইল স্ক্যান করে এবং
android:onClickঅ্যাট্রিবিউট দ্বারা রেফারেন্স করা পদ্ধতির জন্য টার্গেট করা কিপ নিয়ম জেনারেট করে।
'ব্রড ভিউ' গেটার ও সেটার সংক্রান্ত নিয়ম
# Don't do this:
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int);
public void set*(...);
public *** get*();
}
- পারফর্ম্যান্সের উপর এর প্রভাব: এই নিয়মের ফলে R8-কে অ্যাপের প্রতিটি
Viewসাবক্লাস এবং সমস্ত লিঙ্ক করা লাইব্রেরিতে (AndroidX ও Material লাইব্রেরি সহ) প্রতিটি গেটার ও সেটার রেখে দিতে হয়। এর ফলে UI কোড জুড়ে ডেড মেথড সরানো ও ইনলাইনিং ব্লক হয়ে যায়। - সাজেস্ট করা সমাধান: নিয়মটি মুছে দিন। AAPT2 ইতিমধ্যেই কাস্টম
Viewক্লাসের জন্য কনস্ট্রাক্টর সংরক্ষণ করে যা লেআউট XML ফাইল থেকে ইনফলেটেড হয়। কোড যদিObjectAnimator.ofFloat(view, "translationZ", ...)-এর মতো রিফ্লেক্টিভ স্ট্রিং নাম ব্যবহার করে কোনও ভিউ প্রপার্টি অ্যানিমেট করে, তাহলে সম্পূর্ণভাবে রিফ্লেকশন এড়াতে, টাইপ করা প্রপার্টি রেফারেন্স (View.TRANSLATION_Zবা কাস্টমFloatPropertyবাIntPropertyইমপ্লিমেন্টেশন) দিয়ে স্ট্রিং নাম পরিবর্তন করুন। রিফ্লেক্টিভ প্রপার্টি অ্যাক্সেস এড়ানো না গেলে,@UsedByReflectionদিয়ে নির্দিষ্ট গেটার বা সেটারকে অ্যানোটেট করুন।
ব্ল্যাঙ্কেট অপ্টিমাইজেশন বা অবফাসকেশন বন্ধ করে দেয়
# Don't do this in proguard.flags:
-dontoptimize
-dontshrink
-dontobfuscate
- পারফর্ম্যান্সের উপর এর প্রভাব:
.flagsফাইলের মধ্যে-dontoptimizeবা-dontshrinkপ্লেস করলে, তা নীরবে মডিউলেরAndroid.bpসেটিংস ওভাররাইড করে এবং সম্পূর্ণ টার্গেট জুড়ে অপ্টিমাইজেশন পাস বন্ধ করে দেয়। এর চেয়েও খারাপ হল, কোনও লাইব্রেরি-dontoptimizeসহ.flagsফাইল এক্সপোর্ট করলে, এটি লাইব্রেরির সাথে লিঙ্ক করা প্রতিটি ডাউনস্ট্রিমandroid_app-এর জন্য R8 অপ্টিমাইজেশন বন্ধ করে দেয়। - সাজেস্ট করা সমাধান:
.flagsফাইল থেকে-dontoptimize,-dontshrinkও-dontobfuscateসরিয়ে দিন।Android.bp-এ স্পষ্টভাবে অপ্টিমাইজেশন আচরণ কন্ট্রোল করুন, এর জন্য লিফ টার্গেটেoptimizeব্লক (shrink,optimize,obfuscate) ব্যবহার করুন।
কমিট করা নিয়মে ডায়াগনস্টিক ফ্ল্যাগ
# Don't do this in proguard.flags:
-verbose
-printmapping proguard.map
-printusage usage.txt
-printconfiguration config.txt
- বিল্ডের ক্ষতি কেন হয়: স্যান্ডবক্সড Soong বিল্ড চলাকালীন ডায়াগনস্টিক ফ্ল্যাগ বিল্ড লগ ভরে দেয় অথবা স্থানীয় পাথে আউটপুট ফাইল লেখার চেষ্টা করে।
- সাজেস্ট করা সমাধান: কমিট করা
.flagsফাইল থেকে এইসব ফ্ল্যাগ মুছে দিন। Soongout/soong/.intermediates/-এর অধীনে মডিউলের ইন্টারমিডিয়েট ডিরেক্টরিতে R8 ম্যাপিং ও ব্যবহারের আউটপুট, যেমনproguard_dictionaryওproguard_usage.zip, অটোমেটিক লেখে।
টেস্ট কোডের জন্য প্রোডাকশন কীপ সংক্রান্ত নিয়ম
- পারফর্ম্যান্সের উপর এর প্রভাব: শুধুমাত্র টেস্ট
অ্যাক্সেসের জন্য কাস্টম
-keepনিয়ম যোগ করলে, সেই কোডকে প্রোডাকশন বিল্ডে অবফাসকেট না করে রেখে দিতে হয়।@VisibleForTestingদিয়ে পদ্ধতি অ্যানোটেট করা বাtrace_references_fromকনফিগার করা হলে, ম্যানুয়াল-keepনিয়ম আর মেনে চলতে হয় না, তবে সেইসব চিহ্ন এখনও প্রোডাকশন বাইনারিতে থাকে। - সাজেস্ট করা সমাধান: শুধুমাত্র পরীক্ষার জন্য এন্ট্রি পয়েন্টকে প্রোডাকশন APK-এর
বাইরে রাখতে, অ্যাপ্লিকেশনটিকে
.implলাইব্রেরিতে স্ট্রাকচার করুন এবংstatic_libsব্যবহার করে সেটিকে সেল্ফ-ইনস্ট্রুমেন্টিং টেস্ট APK-এর সাথে লিঙ্ক করুন, যেমনটি ধাপ ২: টেস্ট-ড্রিভেন কিপ নিয়ম মাইগ্রেট করুন-এ বর্ণনা করা হয়েছে।
keep.xml-এ ব্ল্যাঙ্কেট রিসোর্স ওয়াইল্ডকার্ড
<!-- Don't do this in res/raw/keep.xml: -->
<resources xmlns:tools="http://schemas.android.com/tools"
tools:keep="@raw/*,@drawable/*,@string/*" />
- পারফর্ম্যান্সের উপর কেন প্রভাব পড়ে: ব্ল্যাঙ্কেট ওয়াইল্ডকার্ড, মডিউল ও তার ডিপেন্ডেন্সি জুড়ে
ম্যাচিং ধরনের প্রতিটি রিসোর্স ধরে রাখে, এর ফলে রিসোর্স
ছোট করা (
shrink_resources: true) যায় না এবং APK ও ম্যাপ করাresources.arscটেবিলের সাইজ বেড়ে যায়। - সাজেস্ট করা সমাধান:
keep.xml-এর পরিবর্তে স্ট্যাটিক রিসোর্স রেফারেন্স ব্যবহার করুন: নম্বরযুক্ত এক্সপেরিমেন্ট স্ট্রিং বা থিমযুক্ত ড্রয়েবলের মতো ডায়নামিক রিসোর্সের একটি বাউন্ডেড সেট খুঁজে দেখতেResources.getIdentifierপদ্ধতি ব্যবহার করা এড়িয়ে চলুন। এর পরিবর্তে, কম্পাইল-টাইমswitchস্টেটমেন্ট বা স্ট্যাটিকR.id,R.stringবাR.drawableকনস্ট্যান্টের উপর ম্যাপ ব্যবহার করুন। স্ট্যাটিক রেফারেন্স R8 ও AAPT2-কে সঠিক লাইভ রিসোর্স ট্রেস করতে, রানটাইম স্ট্রিং লুক-আপ ওভারহেড কমাতে এবংkeep.xml-এর প্রয়োজনীয়তা দূর করতে সাহায্য করে।- নির্দিষ্ট রিসোর্সের নাম তালিকাভুক্ত করুন: থার্ড-পার্টি লাইসেন্স রিডারের মতো
ডায়নামিক লুক-আপের প্রয়োজন হলে,
tools:keep-এ (যেমন,tools:keep="@raw/third_party_licenses") সঠিক রিসোর্স শনাক্তকারী তালিকাভুক্ত করুন। - অপ্রয়োজনীয়
keep.xmlফাইল মুছে দিন: তালিকাভুক্ত রিসোর্স যদি কোড (R.raw.foo) বা XML (@raw/foo)-এ আগে থেকেই স্ট্যাটিক রেফারেন্স করা থাকে, তাহলে শ্রিন্কার সেগুলি অটোমেটিক রেখে দেয়, তাই আপনিres/raw/keep.xmlমুছে দিতে পারবেন।
নিয়মে হওয়া পরিবর্তন যাচাই ও অডিট করা
proguard.flags বা keep.xml-এ কোনও কিপ নিয়ম সরিয়ে দিলে বা ছোট করে দিলে,
মডিউলটি সঠিকভাবে বিল্ড হয়েছে কিনা, ইউনিট ও ইন্সট্রুমেন্টেশন টেস্টে পাস করেছে কিনা
এবং প্রয়োজনীয় সব এন্ট্রি পয়েন্ট বজায় রেখেছে কিনা তা যাচাই করে নিন।
মডিউল তৈরি ও পরীক্ষা করা
R8 ও AAPT2-তে রেফারেন্স সংক্রান্ত সতর্কতা না দেখিয়েই সম্পূর্ণ হয় কিনা তা যাচাই করতে মডিউলটি পরিষ্কারভাবে তৈরি করুন:
m <MODULE_NAME>atestব্যবহার করে মডিউলের জন্য ইউনিট ও ইনস্ট্রুমেন্টেশন টেস্ট চালান:atest <TEST_MODULE_NAME>সিস্টেম অ্যাপ, বিশেষ সুবিধা প্রাপ্ত পরিষেবা বা হার্ডওয়্যার-নির্ভর মডিউলের জন্য, রানটাইম রিফ্লেকশন পাথ, IPC বাইন্ডিং এবং রিসোর্স ইনফ্লেশন প্রয়োগ করতে, টার্গেট ফিজিক্যাল ডিভাইস বা আপনার ডিভাইস টেস্ট ল্যাবে ইন্সট্রুমেন্টেশন ও UI টেস্ট রান করুন।
DEX ও রিসোর্সের পার্থক্য ভালোভাবে দেখুন
নিয়ম পরিবর্তন করার আগে ও পরে কম্পাইল করা APK বা JAR-এর তুলনা করে নিশ্চিত করুন যে R8 প্রত্যাশিত এন্ট্রি পয়েন্ট বাদ না দিয়েই ডেড কোড ও রিসোর্স সরিয়ে দেয়:
আউটপুট APK বা DEX ফাইলে রিটেন করা ক্লাস, মেথড ও ফিল্ড চেক করতে
apkanalyzerবাdexdumpব্যবহার করুন:apkanalyzer dex packages $OUT/system/priv-app/<APP_NAME>/<APP_NAME>.apkkeep.xmlপরিবর্তন বাshrink_resourcesচালু করার সময়, বিল্ড স্ট্রিপ যে অব্যবহৃত রিসোর্স সরিয়ে দেয় এবং প্রয়োজনীয় রিসোর্স রেখে দেয় তা যাচাই করতেaapt2 dump resourcesব্যবহার করুন:aapt2 dump resources $OUT/system/priv-app/<APP_NAME>/<APP_NAME>.apk
R8-এর মাধ্যমে কিপ রেডিয়াস ও রুল সাবসাম্পশন বিশ্লেষণ করা
ওপেন-সোর্স R8 কম্পাইলারে একটি কিপ রেডিয়াস অ্যানালাইজার
(এছাড়াও Android Studio এবং Gradle-এ
R8 কনফিগারেশন অ্যানালাইজার হিসেবে এক্সপোজ করা হয়েছে) অন্তর্ভুক্ত থাকে যা কম্পাইলেশন চলাকালীন প্রতিটি কিপ নিয়মের সঠিক
প্রভাব পরিমাপ করে। Soong এই অ্যানালাইজারকে
সরাসরি Android প্ল্যাটফর্ম বিল্ডে ইন্টিগ্রেট করে (যা
build/soong/java/dex.go-এ কনফিগার করা হয়)।
কোনও প্ল্যাটফর্ম মডিউল বা সম্পূর্ণ বিল্ড জুড়ে কীপ নিয়ম বিশ্লেষণ করতে:
R8_DUMP_KEEP_RADIUS=trueএনভায়রনমেন্ট ভেরিয়েবল সহ বিল্ড চালান:R8_DUMP_KEEP_RADIUS=true m <MODULE_NAME>R8_DUMP_KEEP_RADIUS=trueসেট করা থাকলে, Soong, R8-কেout/soong/.intermediates/-এর অধীনে কম্পাইল করা প্রতিটি মডিউলের জন্য একটি মধ্যবর্তীr8keepradius.pbফাইলে নিয়ম সংক্রান্ত মেট্রিক রেকর্ড করতে নির্দেশ দেয়। প্রতিটি keep rule ওkeepannoঅ্যানোটেশনের জন্য, R8 এগুলি রেকর্ড করে:- অবিলম্বে রেখে দেওয়ার ব্যাসার্ধ: নিয়মের মাধ্যমে রেখে দেওয়া নির্দিষ্ট ক্লাস, ফিল্ড ও পদ্ধতি এবং তার সাথে সাথে ছোট করা, অপ্টিমাইজ করা বা অস্পষ্ট করার বিরুদ্ধে সেটির প্রয়োগ করা নির্দিষ্ট বিধিনিষেধ।
- নিয়ম সাবসাম্পশন: কোন কোন অন্যান্য কিপ নিয়ম বা অ্যানোটেশন ইতিমধ্যেই একই আইটেম ধরে রেখেছে। কোনও কাস্টম নিয়ম যদি কোনও AAPT2 নিয়ম বা গ্লোবাল বেসলাইন নিয়মের মধ্যে সম্পূর্ণভাবে অন্তর্ভুক্ত থাকে, তাহলে আপনি সেটি নিরাপদে মুছে দিতে পারেন।
- প্যাকেজ-ব্যাপী ও গ্লোবাল নিয়ম: এমন নিয়ম যা প্যাকেজ-ব্যাপী ওয়াইল্ডকার্ড ব্যবহার করে বা গ্লোবাল কনফিগারেশন ডাইরেক্টিভ প্রয়োগ করে।
r8keepradius.pbআউটপুটকে ইন্ট্যার্যাক্টিভ HTML রিপোর্টে কনভার্ট করো, এর জন্যKeepRadiusHtmlReportGenerator(prebuilts/r8/r8.jar-এ বান্ডেল করা) ব্যবহার করো:# Generate an HTML report for a single module INTERMEDIATES=out/soong/.intermediates/packages/apps/<APP_NAME>/<APP_NAME> java -cp prebuilts/r8/r8.jar \ com.android.tools.r8.keepradius.KeepRadiusHtmlReportGenerator \ $INTERMEDIATES/android_common/r8keepradius.pb \ keep_radius_report.html # Scan all built modules under out/soong/.intermediates and generate # per-module HTML reports plus an aggregate keepradius.html summary java -cp prebuilts/r8/r8.jar \ com.android.tools.r8.keepradius.KeepRadiusHtmlReportGenerator \ out/soong/.intermediates \ out/keep_radius_reportsকোনও ডিরেক্টরি দেওয়া হলে,
KeepRadiusHtmlReportGeneratorসব*keepradius*.pbফাইল ঘুরে দেখে, প্রতিটি মডিউলের জন্য HTML রিপোর্ট তৈরি করে এবংout/keep_radius_reports/keepradius.htmlলাইভ আইটেমের সারাংশ গণনা, রাখা আইটেমের গণনা এবং বিল্ড জুড়ে সর্বোচ্চ-রেডিয়াস কিপ নিয়ম তৈরি করে। তৈরি করা রিপোর্টে, কোড ছোট করা, অপ্টিমাইজ করা, এবং কোড অস্পষ্ট করা সংক্রান্ত স্কোর ব্যাখ্যা করা সম্পর্কে আরও জানতে, R8 কনফিগারেশন অ্যানালাইজার ব্যবহার করুন দেখুন।
এছাড়াও, Soong-এ
build/soong/java/dex.go-এ দুটি অতিরিক্ত R8 ডায়াগনস্টিক এনভায়রনমেন্ট ভেরিয়েবল কাজ করে:
R8_DUMP_INPUT=true: মডিউলের ইন্টারমিডিয়েট ডিরেক্টরিতেr8inputs.zipলেখে, এতে সমস্ত ইনপুট JAR, লাইব্রেরি JAR এবং স্ট্যান্ডঅলোন R8 রিপ্রোডাকশনের জন্য মার্জ করা ProGuard কনফিগারেশন থাকে।R8_DUMP_PERFETTO_TRACE=true: মডিউলের ইন্টারমিডিয়েট ডিরেক্টরিতেr8trace.ptraceলেখে, যাতে Perfetto-তে R8 কম্পাইলেশন পাস পরীক্ষা করা যায়।
লাইব্রেরি কনজিউমার সংক্রান্ত নিয়ম যাচাই করা
java_library বা android_library এক্সপোর্ট করার সময় ডাউনস্ট্রিম
কনজিউমার (export_proguard_flags_files: true)-এর জন্য নিয়ম মেনে চললে, সেইসব নিয়মের মধ্যে
কনজিউমিং অ্যাপের অপ্টিমাইজেশন পরিবর্তন বা বন্ধ করে দেয় এমন গ্লোবাল ফ্ল্যাগ অন্তর্ভুক্ত করা যাবে না।
R8-এ ওপেন সোর্স কিপ রুল অ্যানালাইজার
(ProcessKeepRules) দেওয়া আছে, যা Android প্ল্যাটফর্মে
process-keep-rules হোস্ট টুল হিসেবে বিল্ড করা হয়েছে (যা
prebuilts/r8/Android.bp-এ সংজ্ঞায়িত করা হয়েছে):
# Build the R8 keep rules validator host binary
m process-keep-rules
# Validate one or more ProGuard configuration files
out/host/linux-x86/bin/process-keep-rules <PROGUARD_FLAGS_PATH>
process-keep-rules টুল প্রতিটি কনফিগারেশন ফাইল পার্স করে এবং লাইব্রেরি
কনজিউমার নিয়মে অনুমোদিত নয় এমন ডাইরেক্টিভ দেখতে পেলে ফাইল
ও লাইন ডায়াগনস্টিকস সহ ব্যর্থ হয়। অনুমতি না থাকা ডাইরেক্টিভের মধ্যে রয়েছে গ্লোবাল অপ্টিমাইজেশন, সাইজ কমানো,
বা অস্পষ্টতা বন্ধ করা (যেমন -dontoptimize বা -dontshrink), প্যাকেজ
আবার প্যাকেজ করা এবং অ্যাক্সেস পরিবর্তন করা ফ্ল্যাগ, ডায়াগনস্টিক বা ম্যাপিং ফ্ল্যাগ এবং
অ্যাপ-লেভেল -keepattributes।
pgaudit.py-এর মাধ্যমে সোর্স ট্রি অডিট করা
R8-এর বিল্ড-টাইম অ্যানালাইজার ছাড়াও, বিল্ড না করা সোর্স ডিরেক্টরি অডিট করতে,
Android প্ল্যাটফর্ম ট্রি-তে pgaudit.py স্ক্রিপ্ট
build/make/core/proguard/tools/-এর অধীনে অন্তর্ভুক্ত থাকে। এই স্ট্যাটিক অ্যানালিসিস টুল, AAPT2 বা গ্লোবাল প্ল্যাটফর্ম বেসলাইন, ওয়াইল্ডকার্ড, -dontoptimize
ওভাররাইড এবং শুধুমাত্র পরীক্ষার জন্য প্রযোজ্য কিপ রুল দ্বারা আগে থেকেই কভার করা নিয়মগুলিকে ফ্ল্যাগ করতে, একটি রেপোজিটরি জুড়ে Android.bp, proguard.flags এবং keep.xml ফাইল স্ক্যান করে:
# Audit a single package directory
./build/make/core/proguard/tools/pgaudit.py packages/apps/Provision/
# Scan a subsystem tree and write a structured JSON report
./build/make/core/proguard/tools/pgaudit.py packages/ --json=audit_report.json
দ্রুত সোর্স-ট্রি ট্রায়াজ করার জন্য প্ল্যাটফর্ম ও OEM টিম pgaudit.py,
এক্সপোর্ট করা লাইব্রেরি নিয়ম যাচাই করার জন্য process-keep-rules এবং
R8_DUMP_KEEP_RADIUS=true-এর সাথে KeepRadiusHtmlReportGenerator মিলিয়ে
বিল্ডের প্রতিটি নিয়মের সঠিক ক্লাস, ফিল্ড ও মেথড রিটেনশন রেডিয়াস পরিমাপ করতে পারে।