অ্যাপ্লিকেশন বাইনারি ইন্টারফেস (ABI) স্থায়িত্ব হল ফ্রেমওয়ার্ক-শুধু আপডেটের পূর্বশর্ত কারণ ভেন্ডর মডিউলগুলি ভেন্ডর নেটিভ ডেভেলপমেন্ট কিট (VNDK) শেয়ার্ড লাইব্রেরির উপর নির্ভর করতে পারে যা সিস্টেম পার্টিশনে থাকে। একটি অ্যান্ড্রয়েড রিলিজের মধ্যে, নতুন-নির্মিত VNDK ভাগ করা লাইব্রেরিগুলিকে পূর্বে প্রকাশিত VNDK ভাগ করা লাইব্রেরির সাথে ABI-সামঞ্জস্যপূর্ণ হতে হবে যাতে বিক্রেতা মডিউলগুলি পুনরায় সংকলন ছাড়াই এবং রানটাইম ত্রুটি ছাড়াই সেই লাইব্রেরির সাথে কাজ করতে পারে। অ্যান্ড্রয়েড রিলিজের মধ্যে, ভিএনডিকে লাইব্রেরি পরিবর্তন করা যেতে পারে এবং কোন ABI গ্যারান্টি নেই।
ABI সামঞ্জস্য নিশ্চিত করতে সাহায্য করার জন্য, Android 9-এ একটি শিরোনাম ABI চেকার রয়েছে, যা নিম্নলিখিত বিভাগে বর্ণিত হয়েছে।
VNDK এবং ABI সম্মতি সম্পর্কে
VNDK হল লাইব্রেরির একটি বিধিনিষেধমূলক সেট যেখানে বিক্রেতা মডিউলগুলি লিঙ্ক করতে পারে এবং যা শুধুমাত্র ফ্রেমওয়ার্ক আপডেটগুলি সক্ষম করে। ABI সম্মতি বলতে একটি শেয়ার্ড লাইব্রেরির একটি নতুন সংস্করণের সাথে গতিশীলভাবে যুক্ত একটি মডিউলের সাথে প্রত্যাশিতভাবে কাজ করার ক্ষমতা বোঝায় (যেমন লাইব্রেরির একটি পুরানো সংস্করণ হিসাবে কাজ করে)।
রপ্তানি প্রতীক সম্পর্কে
একটি রপ্তানিকৃত চিহ্ন (একটি বৈশ্বিক প্রতীক হিসাবেও পরিচিত) এমন একটি প্রতীককে বোঝায় যা নিম্নলিখিত সমস্তকে সন্তুষ্ট করে:
- একটি শেয়ার্ড লাইব্রেরির পাবলিক হেডার দ্বারা রপ্তানি করা হয়েছে৷
- শেয়ার করা লাইব্রেরির সাথে সম্পর্কিত
.so
ফাইলের.dynsym
টেবিলে উপস্থিত হয়। - দুর্বল বা গ্লোবাল বাইন্ডিং আছে।
- দৃশ্যমানতা ডিফল্ট বা সুরক্ষিত।
- বিভাগ সূচক অনির্ধারিত নয়।
- টাইপ হয় FUNC বা OBJECT।
শেয়ার্ড লাইব্রেরির পাবলিক হেডারগুলিকে export_include_dirs
, export_header_lib_headers
, export_static_lib_headers
, export_shared_lib_headers
, এবং export_generated_headers
বৈশিষ্ট্যগুলির মাধ্যমে অন্যান্য লাইব্রেরি/বাইনারিতে উপলব্ধ হেডার হিসাবে সংজ্ঞায়িত করা হয় Android.bp
নাগালযোগ্য ধরনের সম্পর্কে
একটি পৌঁছানো যায় এমন ধরন হল যেকোন C/C++ অন্তর্নির্মিত বা ব্যবহারকারী-সংজ্ঞায়িত প্রকার যা সরাসরি বা পরোক্ষভাবে রপ্তানি করা প্রতীকের মাধ্যমে পৌঁছানো যায় এবং পাবলিক হেডারের মাধ্যমে রপ্তানি করা হয়। উদাহরণস্বরূপ, libfoo.so
Foo
ফাংশন রয়েছে, যা .dynsym
টেবিলে পাওয়া একটি রপ্তানি প্রতীক। libfoo.so
লাইব্রেরিতে নিম্নলিখিতগুলি অন্তর্ভুক্ত রয়েছে:
foo_exported.h | foo.private.h |
---|---|
typedef struct foo_private foo_private_t; typedef struct foo { int m1; int *m2; foo_private_t *mPfoo; } foo_t; typedef struct bar { foo_t mfoo; } bar_t; bool Foo(int id, bar_t *bar_ptr); | typedef struct foo_private { int m1; float mbar; } foo_private_t; |
Android.bp |
---|
cc_library { name : libfoo, vendor_available: true, vndk { enabled : true, } srcs : ["src/*.cpp"], export_include_dirs : [ "exported" ], } |
.dynsym টেবিল | |||||||
---|---|---|---|---|---|---|---|
Num | Value | Size | Type | Bind | Vis | Ndx | Name |
1 | 0 | 0 | FUNC | GLOB | DEF | UND | dlerror@libc |
2 | 1ce0 | 20 | FUNC | GLOB | DEF | 12 | Foo |
Foo
দিকে তাকালে, প্রত্যক্ষ/পরোক্ষভাবে পৌঁছানো যায় এমন প্রকারের মধ্যে রয়েছে:
টাইপ | বর্ণনা |
---|---|
bool | Foo এর রিটার্ন টাইপ। |
int | প্রথম Foo প্যারামিটারের ধরন। |
bar_t * | দ্বিতীয় Foo প্যারামিটারের ধরন। bar_t * এর মাধ্যমে, bar_t foo_exported.h এর মাধ্যমে রপ্তানি করা হয়।bar_t একটি সদস্য mfoo রয়েছে, foo_t টাইপের, যেটি foo_exported.h এর মাধ্যমে রপ্তানি করা হয়, যার ফলে আরও ধরনের রপ্তানি হয়:
যাইহোক, foo_private_t পৌঁছানো যায় না কারণ এটি foo_exported.h মাধ্যমে রপ্তানি হয় না। ( foo_private_t * অস্বচ্ছ, তাই foo_private_t এ করা পরিবর্তন অনুমোদিত।) |
বেস ক্লাস স্পেসিফায়ার এবং টেমপ্লেট পরামিতিগুলির মাধ্যমেও পৌঁছানো যায় এমন ধরণের জন্য অনুরূপ ব্যাখ্যা দেওয়া যেতে পারে।
ABI সম্মতি নিশ্চিত করুন
vendor_available: true
এবং vndk.enabled: সংশ্লিষ্ট Android.bp
ফাইলগুলিতে vndk.enabled: true
। যেমন:
cc_library { name: "libvndk_example", vendor_available: true, vndk: { enabled: true, } }
রপ্তানিকৃত ফাংশন দ্বারা প্রত্যক্ষ বা পরোক্ষভাবে পৌঁছানো ডেটা প্রকারের জন্য, একটি লাইব্রেরিতে নিম্নলিখিত পরিবর্তনগুলি ABI-ব্রেকিং হিসাবে শ্রেণীবদ্ধ করা হয়েছে:
ডেটা টাইপ | বর্ণনা |
---|---|
স্ট্রাকচার এবং ক্লাস |
|
ইউনিয়ন |
|
গণনা |
|
গ্লোবাল সিম্বল |
|
* উভয় পাবলিক এবং প্রাইভেট সদস্য ফাংশন পরিবর্তন বা অপসারণ করা উচিত নয় কারণ পাবলিক ইনলাইন ফাংশন ব্যক্তিগত সদস্য ফাংশন উল্লেখ করতে পারে। ব্যক্তিগত সদস্য ফাংশনের প্রতীক উল্লেখগুলি কলার বাইনারিগুলিতে রাখা যেতে পারে। ভাগ করা লাইব্রেরি থেকে ব্যক্তিগত সদস্য ফাংশন পরিবর্তন বা অপসারণের ফলে পশ্চাদগামী-অসঙ্গত বাইনারি হতে পারে।
** সর্বজনীন বা ব্যক্তিগত ডেটা সদস্যদের অফসেটগুলি অবশ্যই পরিবর্তন করা উচিত নয় কারণ ইনলাইন ফাংশনগুলি তাদের ফাংশন বডিতে এই ডেটা সদস্যদের উল্লেখ করতে পারে। ডেটা সদস্য অফসেটগুলি পরিবর্তন করার ফলে পশ্চাদপদ-বেমানান বাইনারি হতে পারে।
*** যদিও এগুলি টাইপের মেমরি লেআউট পরিবর্তন করে না, সেখানে শব্দার্থগত পার্থক্য রয়েছে যা লাইব্রেরিগুলি প্রত্যাশিত হিসাবে কাজ করতে পারে না।
ABI কমপ্লায়েন্স টুল ব্যবহার করুন
যখন একটি VNDK লাইব্রেরি তৈরি করা হয়, তখন লাইব্রেরির ABI-কে VNDK-এর সংস্করণের জন্য সংশ্লিষ্ট ABI রেফারেন্সের সাথে তুলনা করা হয়। রেফারেন্স ABI ডাম্প এখানে অবস্থিত:
${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/<PLATFORM_VNDK_VERSION>/<BINDER_BITNESS>/<ARCH>/source-based
উদাহরণস্বরূপ, API স্তর 27-এ x86-এর জন্য libfoo
তৈরি করার সময়, libfoo
এর অনুমানকৃত ABI-কে এর রেফারেন্সের সাথে তুলনা করা হয়েছে:
${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/27/64/x86/source-based/libfoo.so.lsdump
ABI ভাঙ্গন ত্রুটি
এবিআই ব্রেকেজের ক্ষেত্রে, বিল্ড লগ সতর্কতার ধরন এবং এবি-ডিফ রিপোর্টের পথ সহ সতর্কতা প্রদর্শন করে। উদাহরণস্বরূপ, যদি libbinder
এর ABI-তে একটি বেমানান পরিবর্তন থাকে, তাহলে বিল্ড সিস্টেম নিম্নলিখিতগুলির মতো একটি বার্তা সহ একটি ত্রুটি ছুড়ে দেয়:
***************************************************** error: VNDK library: libbinder.so's ABI has INCOMPATIBLE CHANGES Please check compatibility report at: out/soong/.intermediates/frameworks/native/libs/binder/libbinder/android_arm64_armv8-a_cortex-a73_vendor_shared/libbinder.so.abidiff ****************************************************** ---- Please update abi references by running platform/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l libbinder ----
VNDK লাইব্রেরি ABI চেক তৈরি করুন
যখন একটি VNDK লাইব্রেরি নির্মিত হয়:
-
header-abi-dumper
VNDK লাইব্রেরি (লাইব্রেরির নিজস্ব সোর্স ফাইলের পাশাপাশি স্ট্যাটিক ট্রানজিটিভ নির্ভরতার মাধ্যমে উত্তরাধিকার সূত্রে প্রাপ্ত সোর্স ফাইল) তৈরি করতে কম্পাইল করা সোর্স ফাইলগুলিকে প্রক্রিয়া করে, প্রতিটি উৎসের সাথে সঙ্গতিপূর্ণ.sdump
ফাইল তৈরি করতে।চিত্র 1. .sdump
ফাইল তৈরি করা হচ্ছে -
header-abi-linker
তারপর একটি.sdump
ফাইল তৈরি করতে.lsdump
ফাইলগুলিকে প্রসেস করে (হয় এটিতে দেওয়া একটি সংস্করণ স্ক্রিপ্ট ব্যবহার করে বা শেয়ার করা লাইব্রেরির সাথে সম্পর্কিত.so
ফাইলটি ব্যবহার করে) যা শেয়ার করা লাইব্রেরির সাথে সম্পর্কিত ABI তথ্য লগ করে।চিত্র 2. .lsdump
ফাইল তৈরি করা হচ্ছে -
header-abi-diff
.lsdump
ফাইলটিকে একটি রেফারেন্স.lsdump
ফাইলের সাথে তুলনা করে একটি ভিন্ন প্রতিবেদন তৈরি করে যা দুটি লাইব্রেরির ABI-এর মধ্যে পার্থক্যকে রূপরেখা দেয়।চিত্র 3. ডিফ রিপোর্ট তৈরি করা
হেডার-আবি-ডাম্পার
header-abi-dumper
টুলটি একটি C/C++ সোর্স ফাইল পার্স করে এবং সেই সোর্স ফাইল থেকে অনুমান করা ABIকে একটি মধ্যবর্তী ফাইলে ডাম্প করে। বিল্ড সিস্টেম সমস্ত কম্পাইল করা সোর্স ফাইলে header-abi-dumper
চালায় এবং একটি লাইব্রেরি তৈরি করে যাতে ট্রানজিটিভ নির্ভরতা থেকে সোর্স ফাইল অন্তর্ভুক্ত থাকে।
ইনপুট |
|
---|---|
আউটপুট | একটি ফাইল যা উৎস ফাইলের ABI বর্ণনা করে (উদাহরণস্বরূপ, foo.sdump foo.cpp এর ABI প্রতিনিধিত্ব করে)। |
বর্তমানে .sdump
ফাইলগুলি JSON ফর্ম্যাটে রয়েছে, যা ভবিষ্যতের রিলিজগুলিতে স্থিতিশীল হওয়ার নিশ্চয়তা নেই৷ যেমন, .sdump
ফাইল ফরম্যাটিং একটি বিল্ড সিস্টেম বাস্তবায়ন বিশদ হিসাবে বিবেচনা করা উচিত।
উদাহরণস্বরূপ, libfoo.so
নিম্নলিখিত উত্স ফাইল foo.cpp
রয়েছে:
#include <stdio.h> #include <foo_exported.h> bool Foo(int id, bar_t *bar_ptr) { if (id > 0 && bar_ptr->mfoo.m1 > 0) { return true; } return false; }
আপনি একটি মধ্যবর্তী .sdump
ফাইল তৈরি করতে header-abi-dumper
ব্যবহার করতে পারেন যা ব্যবহার করে উৎস ফাইল দ্বারা উপস্থাপিত ABI প্রতিনিধিত্ব করে:
$ header-abi-dumper foo.cpp -I exported -o foo.sdump -- -I exported -x c++
এই কমান্ড header-abi-dumper
অনুসরণ করে কম্পাইলার ফ্ল্যাগগুলির সাথে foo.cpp
পার্স করতে বলে --
এবং ABI তথ্য নির্গত করে যা exported
ডিরেক্টরিতে পাবলিক হেডার দ্বারা এক্সপোর্ট করা হয়। নিম্নলিখিত header-abi-dumper
দ্বারা উত্পন্ন foo.sdump
:
{ "array_types" : [], "builtin_types" : [ { "alignment" : 4, "is_integral" : true, "linker_set_key" : "_ZTIi", "name" : "int", "referenced_type" : "_ZTIi", "self_type" : "_ZTIi", "size" : 4 } ], "elf_functions" : [], "elf_objects" : [], "enum_types" : [], "function_types" : [], "functions" : [ { "function_name" : "FooBad", "linker_set_key" : "_Z6FooBadiP3foo", "parameters" : [ { "referenced_type" : "_ZTIi" }, { "referenced_type" : "_ZTIP3foo" } ], "return_type" : "_ZTI3bar", "source_file" : "exported/foo_exported.h" } ], "global_vars" : [], "lvalue_reference_types" : [], "pointer_types" : [ { "alignment" : 8, "linker_set_key" : "_ZTIP11foo_private", "name" : "foo_private *", "referenced_type" : "_ZTI11foo_private", "self_type" : "_ZTIP11foo_private", "size" : 8, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "linker_set_key" : "_ZTIP3foo", "name" : "foo *", "referenced_type" : "_ZTI3foo", "self_type" : "_ZTIP3foo", "size" : 8, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "linker_set_key" : "_ZTIPi", "name" : "int *", "referenced_type" : "_ZTIi", "self_type" : "_ZTIPi", "size" : 8, "source_file" : "exported/foo_exported.h" } ], "qualified_types" : [], "record_types" : [ { "alignment" : 8, "fields" : [ { "field_name" : "mfoo", "referenced_type" : "_ZTI3foo" } ], "linker_set_key" : "_ZTI3bar", "name" : "bar", "referenced_type" : "_ZTI3bar", "self_type" : "_ZTI3bar", "size" : 24, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "fields" : [ { "field_name" : "m1", "referenced_type" : "_ZTIi" }, { "field_name" : "m2", "field_offset" : 64, "referenced_type" : "_ZTIPi" }, { "field_name" : "mPfoo", "field_offset" : 128, "referenced_type" : "_ZTIP11foo_private" } ], "linker_set_key" : "_ZTI3foo", "name" : "foo", "referenced_type" : "_ZTI3foo", "self_type" : "_ZTI3foo", "size" : 24, "source_file" : "exported/foo_exported.h" } ], "rvalue_reference_types" : [] }
foo.sdump
ABI তথ্য রয়েছে যা উত্স ফাইল foo.cpp
এবং পাবলিক হেডার দ্বারা রপ্তানি করা হয়, উদাহরণস্বরূপ,
-
record_types
পাবলিক হেডারে সংজ্ঞায়িত স্ট্রাকট, ইউনিয়ন বা শ্রেণীগুলি পড়ুন। প্রতিটি রেকর্ডের ক্ষেত্র, এর আকার, অ্যাক্সেস স্পেসিফায়ার, এটিতে সংজ্ঞায়িত হেডার ফাইল এবং অন্যান্য বৈশিষ্ট্য সম্পর্কে তথ্য রয়েছে। -
pointer_types
। রপ্তানিকৃত রেকর্ড/ফাংশন দ্বারা সর্বজনীন শিরোনামে প্রত্যক্ষ/পরোক্ষভাবে উল্লেখ করা পয়েন্টার প্রকারগুলি উল্লেখ করুন, সাথে পয়েন্টার যে ধরনের নির্দেশ করে (type_info
এreferenced_type
ক্ষেত্রের মাধ্যমে)। যোগ্য ধরনের, অন্তর্নির্মিত C/C++ প্রকার, অ্যারে প্রকার এবং lvalue এবং rvalue রেফারেন্স প্রকারের জন্য অনুরূপ তথ্য.sdump
ফাইলে লগ করা হয়েছে। এই ধরনের তথ্য পুনরাবৃত্তিমূলক পার্থক্যের অনুমতি দেয়। -
functions
পাবলিক হেডার দ্বারা রপ্তানি করা ফাংশন প্রতিনিধিত্ব করে। তাদের কাছে ফাংশনের ম্যাংগলড নাম, রিটার্নের ধরন, প্যারামিটারের ধরন, অ্যাক্সেস স্পেসিফায়ার এবং অন্যান্য বৈশিষ্ট্য সম্পর্কেও তথ্য রয়েছে।
হেডার-অবি-লিঙ্কার
header-abi-linker
টুলটি header-abi-dumper
দ্বারা উত্পাদিত মধ্যবর্তী ফাইলগুলিকে ইনপুট হিসাবে নেয় তারপর সেই ফাইলগুলিকে লিঙ্ক করে:
ইনপুট |
|
---|---|
আউটপুট | একটি ফাইল যা একটি ভাগ করা লাইব্রেরির ABI বর্ণনা করে (উদাহরণস্বরূপ, libfoo.so.lsdump libfoo এর ABI প্রতিনিধিত্ব করে)। |
টুলটি প্রদত্ত সমস্ত মধ্যবর্তী ফাইলের টাইপ গ্রাফগুলিকে একত্রিত করে, এক-সংজ্ঞা বিবেচনা করে (বিভিন্ন অনুবাদ ইউনিটে একই সম্পূর্ণ যোগ্য নামের ব্যবহারকারী-সংজ্ঞায়িত প্রকার, শব্দার্থগতভাবে ভিন্ন হতে পারে) অনুবাদ ইউনিট জুড়ে পার্থক্য। টুলটি তখন হয় একটি সংস্করণ স্ক্রিপ্ট বা ভাগ করা লাইব্রেরির .dynsym
টেবিলকে পার্স করে ( .so
ফাইল) এক্সপোর্ট করা চিহ্নগুলির একটি তালিকা তৈরি করতে।
উদাহরণস্বরূপ, libfoo
foo.cpp
এবং bar.cpp
নিয়ে গঠিত। libfoo
এর সম্পূর্ণ লিঙ্কযুক্ত ABI ডাম্প তৈরি করতে header-abi-linker
আহ্বান করা যেতে পারে:
header-abi-linker -I exported foo.sdump bar.sdump \ -o libfoo.so.lsdump \ -so libfoo.so \ -arch arm64 -api current
libfoo.so.lsdump
এ কমান্ড আউটপুটের উদাহরণ:
{ "array_types" : [], "builtin_types" : [ { "alignment" : 1, "is_integral" : true, "is_unsigned" : true, "linker_set_key" : "_ZTIb", "name" : "bool", "referenced_type" : "_ZTIb", "self_type" : "_ZTIb", "size" : 1 }, { "alignment" : 4, "is_integral" : true, "linker_set_key" : "_ZTIi", "name" : "int", "referenced_type" : "_ZTIi", "self_type" : "_ZTIi", "size" : 4 } ], "elf_functions" : [ { "name" : "_Z3FooiP3bar" }, { "name" : "_Z6FooBadiP3foo" } ], "elf_objects" : [], "enum_types" : [], "function_types" : [], "functions" : [ { "function_name" : "Foo", "linker_set_key" : "_Z3FooiP3bar", "parameters" : [ { "referenced_type" : "_ZTIi" }, { "referenced_type" : "_ZTIP3bar" } ], "return_type" : "_ZTIb", "source_file" : "exported/foo_exported.h" }, { "function_name" : "FooBad", "linker_set_key" : "_Z6FooBadiP3foo", "parameters" : [ { "referenced_type" : "_ZTIi" }, { "referenced_type" : "_ZTIP3foo" } ], "return_type" : "_ZTI3bar", "source_file" : "exported/foo_exported.h" } ], "global_vars" : [], "lvalue_reference_types" : [], "pointer_types" : [ { "alignment" : 8, "linker_set_key" : "_ZTIP11foo_private", "name" : "foo_private *", "referenced_type" : "_ZTI11foo_private", "self_type" : "_ZTIP11foo_private", "size" : 8, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "linker_set_key" : "_ZTIP3bar", "name" : "bar *", "referenced_type" : "_ZTI3bar", "self_type" : "_ZTIP3bar", "size" : 8, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "linker_set_key" : "_ZTIP3foo", "name" : "foo *", "referenced_type" : "_ZTI3foo", "self_type" : "_ZTIP3foo", "size" : 8, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "linker_set_key" : "_ZTIPi", "name" : "int *", "referenced_type" : "_ZTIi", "self_type" : "_ZTIPi", "size" : 8, "source_file" : "exported/foo_exported.h" } ], "qualified_types" : [], "record_types" : [ { "alignment" : 8, "fields" : [ { "field_name" : "mfoo", "referenced_type" : "_ZTI3foo" } ], "linker_set_key" : "_ZTI3bar", "name" : "bar", "referenced_type" : "_ZTI3bar", "self_type" : "_ZTI3bar", "size" : 24, "source_file" : "exported/foo_exported.h" }, { "alignment" : 8, "fields" : [ { "field_name" : "m1", "referenced_type" : "_ZTIi" }, { "field_name" : "m2", "field_offset" : 64, "referenced_type" : "_ZTIPi" }, { "field_name" : "mPfoo", "field_offset" : 128, "referenced_type" : "_ZTIP11foo_private" } ], "linker_set_key" : "_ZTI3foo", "name" : "foo", "referenced_type" : "_ZTI3foo", "self_type" : "_ZTI3foo", "size" : 24, "source_file" : "exported/foo_exported.h" } ], "rvalue_reference_types" : [] }
header-abi-linker
টুল:
- এটিতে প্রদত্ত
.sdump
ফাইলগুলিকে লিঙ্ক করে (foo.sdump
এবংbar.sdump
), ডিরেক্টরিতে থাকা হেডারগুলিতে উপস্থিত না থাকা ABI তথ্য ফিল্টার করে:exported
। -
libfoo.so
পার্স করে, এবং লাইব্রেরি দ্বারা রপ্তানি করা চিহ্ন সম্পর্কে তথ্য সংগ্রহ করে তার.dynsym
টেবিলের মাধ্যমে। -
_Z3FooiP3bar
এবং_Z6FooBadiP3foo
যোগ করে।
libfoo.so.lsdump
হল libfoo.so
এর চূড়ান্ত জেনারেট করা ABI ডাম্প।
হেডার-আবি-ডিফ
header-abi-diff
টুল দুটি লাইব্রেরির ABI প্রতিনিধিত্বকারী দুটি .lsdump
ফাইলের তুলনা করে এবং দুটি ABI-এর মধ্যে পার্থক্য উল্লেখ করে একটি ভিন্ন প্রতিবেদন তৈরি করে।
ইনপুট |
|
---|---|
আউটপুট | তুলনা করা দুটি শেয়ার্ড লাইব্রেরি দ্বারা প্রদত্ত ABI-এর পার্থক্য উল্লেখ করে একটি ভিন্ন প্রতিবেদন। |
ABI ডিফ ফাইলটি প্রোটোবাফ টেক্সট ফরম্যাটে রয়েছে। বিন্যাস ভবিষ্যতে রিলিজ পরিবর্তন সাপেক্ষে.
উদাহরণস্বরূপ, আপনার libfoo
এর দুটি সংস্করণ রয়েছে: libfoo_old.so
এবং libfoo_new.so
। libfoo_new.so
এ, bar_t
এ, আপনি mfoo
এর ধরন foo_t
থেকে foo_t *
এ পরিবর্তন করেন। যেহেতু bar_t
একটি পৌঁছানো যায় এমন প্রকার, এটিকে header-abi-diff
দ্বারা ABI ব্রেকিং পরিবর্তন হিসাবে পতাকাঙ্কিত করা উচিত।
header-abi-diff
চালানোর জন্য:
header-abi-diff -old libfoo_old.so.lsdump \ -new libfoo_new.so.lsdump \ -arch arm64 \ -o libfoo.so.abidiff \ -lib libfoo
libfoo.so.abidiff
এ কমান্ড আউটপুটের উদাহরণ:
lib_name: "libfoo" arch: "arm64" record_type_diffs { name: "bar" type_stack: "Foo-> bar *->bar " type_info_diff { old_type_info { size: 24 alignment: 8 } new_type_info { size: 8 alignment: 8 } } fields_diff { old_field { referenced_type: "foo" field_offset: 0 field_name: "mfoo" access: public_access } new_field { referenced_type: "foo *" field_offset: 0 field_name: "mfoo" access: public_access } } }
libfoo.so.abidiff
libfoo
এ ABI-এর সমস্ত পরিবর্তনের রিপোর্ট রয়েছে। record_type_diffs
বার্তাটি নির্দেশ করে যে একটি রেকর্ড পরিবর্তিত হয়েছে এবং অসঙ্গত পরিবর্তনগুলি তালিকাভুক্ত করে, যার মধ্যে রয়েছে:
- রেকর্ডের আকার
24
বাইট থেকে8
বাইটে পরিবর্তিত হচ্ছে। -
mfoo
এর ক্ষেত্রের ধরনfoo
থেকেfoo *
তে পরিবর্তিত হচ্ছে (সমস্ত টাইপডেফ বন্ধ করে দেওয়া হয়েছে)।
type_stack
ক্ষেত্র নির্দেশ করে কিভাবে header-abi-diff
পরিবর্তিত প্রকারে পৌঁছেছে ( bar
)। এই ক্ষেত্রটিকে ব্যাখ্যা করা যেতে পারে Foo
হল একটি রপ্তানিকৃত ফাংশন যা bar *
প্যারামিটার হিসাবে নেয়, যা bar
নির্দেশ করে, যা রপ্তানি এবং পরিবর্তিত হয়েছিল।
ABI এবং API প্রয়োগ করুন
VNDK ভাগ করা লাইব্রেরির ABI এবং API প্রয়োগ করতে, ABI রেফারেন্সগুলি অবশ্যই ${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/
এ চেক করতে হবে। এই রেফারেন্স তৈরি করতে, নিম্নলিখিত কমান্ডটি চালান:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py
রেফারেন্স তৈরি করার পর, সোর্স কোডে করা যেকোন পরিবর্তনের ফলে VNDK লাইব্রেরিতে একটি বেমানান ABI/API পরিবর্তনের ফলে এখন একটি বিল্ড ত্রুটি দেখা দেয়।
নির্দিষ্ট লাইব্রেরির জন্য ABI রেফারেন্স আপডেট করতে, নিম্নলিখিত কমান্ডটি চালান:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l <lib1> -l <lib2>
উদাহরণস্বরূপ, libbinder
ABI রেফারেন্স আপডেট করতে, চালান:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l libbinder