ऐप्लिकेशन बाइनरी इंटरफ़ेस (एबीआई) की स्थिरता, सिर्फ़ फ़्रेमवर्क के अपडेट के लिए एक ज़रूरी शर्त है. इसकी वजह यह है कि वेंडर मॉड्यूल, सिस्टम पार्टिशन में मौजूद वेंडर नेटिव डेवलपमेंट किट (वीएनडीके) की शेयर की गई लाइब्रेरी पर निर्भर हो सकते हैं. किसी Android रिलीज़ में, नई बनाई गई VNDK शेयर की गई लाइब्रेरी, पहले रिलीज़ की गई VNDK शेयर की गई लाइब्रेरी के साथ एबीआई के हिसाब से काम करनी चाहिए, ताकि वेंडर मॉड्यूल, उन लाइब्रेरी के साथ फिर से कंपाइल किए बिना और रनटाइम गड़बड़ियों के बिना काम कर सकें. Android रिलीज़ के बीच, VNDK लाइब्रेरी बदली जा सकती हैं और एबीआई के काम करने की कोई गारंटी नहीं है.
एबीआई के साथ काम करने की सुविधा देने के लिए, Android 9 में हेडर एबीआई चेकर शामिल किया गया है. इस बारे में यहां बताया गया है.
VNDK और एबीआई के अनुपालन के बारे में जानकारी
VNDK, लाइब्रेरी का एक ऐसा सेट है जिस पर पाबंदी लगी होती है. वेंडर मॉड्यूल, इस सेट से लिंक किए जा सकते हैं और सिर्फ़ फ़्रेमवर्क के अपडेट चालू किए जा सकते हैं. एबीआई के मुताबिक होना का मतलब है कि शेयर की गई लाइब्रेरी के नए वर्शन में, उससे डाइनैमिक तौर पर लिंक किए गए मॉड्यूल के साथ उम्मीद के मुताबिक काम करने की सुविधा हो. इसका मतलब है कि लाइब्रेरी का नया वर्शन, लाइब्रेरी के पुराने वर्शन की तरह काम करे.
एक्सपोर्ट किए गए सिंबल के बारे में जानकारी
एक्सपोर्ट किया गया सिंबल (इसे ग्लोबल सिंबल भी कहा जाता है) का मतलब ऐसे सिंबल से है जो इन सभी शर्तों को पूरा करता है:
- शेयर की गई लाइब्रेरी के सार्वजनिक हेडर से एक्सपोर्ट किया जाता है.
- शेयर की गई लाइब्रेरी से जुड़ी
.so
फ़ाइल की.dynsym
टेबल में दिखता है. - WEAK या ग्लोबल बाइंडिंग है.
- वीडियो किसे दिखेगा, यह डिफ़ॉल्ट या सुरक्षित है.
- सेक्शन का इंडेक्स, UNDEFINED नहीं है.
- टाइप, FUNC या OBJECT में से कोई एक होता है.
किसी शेयर की गई लाइब्रेरी के सार्वजनिक हेडर, अन्य लाइब्रेरी/बाइनरी के लिए उपलब्ध हेडर के तौर पर तय किए जाते हैं. ऐसा, शेयर की गई लाइब्रेरी से जुड़े मॉड्यूल की Android.bp
परिभाषाओं में export_include_dirs
, export_header_lib_headers
, export_static_lib_headers
, export_shared_lib_headers
, और export_generated_headers
एट्रिब्यूट के ज़रिए किया जाता है.
पहुंच के लिए उपलब्ध टाइप के बारे में जानकारी
ऐसा टाइप जिसे ऐक्सेस किया जा सकता है, 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 में foo_t टाइप का एक सदस्य mfoo है, जिसे foo_exported.h के ज़रिए एक्सपोर्ट किया जाता है. इससे, ज़्यादा टाइप एक्सपोर्ट किए जाते हैं:
हालांकि, foo_private_t को ऐक्सेस नहीं किया जा सकता, क्योंकि इसे foo_exported.h के ज़रिए एक्सपोर्ट नहीं किया गया है. (foo_private_t *
पारदर्शी नहीं है, इसलिए foo_private_t में किए गए बदलावों की अनुमति है.)
|
ऐसा ही एक उदाहरण, बेस क्लास स्पेसिफ़िकेशन और टेंप्लेट पैरामीटर की मदद से ऐक्सेस किए जा सकने वाले टाइप के लिए भी दिया जा सकता है.
एबीआई से जुड़ी नीति का पालन करना
इससे जुड़ी Android.bp
फ़ाइलों में vendor_available: true
और vndk.enabled: true
के तौर पर मार्क की गई लाइब्रेरी के लिए, एबीआई का पालन करना ज़रूरी है. उदाहरण के लिए:
cc_library { name: "libvndk_example", vendor_available: true, vndk: { enabled: true, } }
एक्सपोर्ट किए गए फ़ंक्शन से सीधे या किसी अन्य तरीके से ऐक्सेस किए जा सकने वाले डेटा टाइप के लिए, लाइब्रेरी में किए गए इन बदलावों को एबीआई (एबिट्रेशन इंटरफ़ेस) को तोड़ने वाले बदलावों के तौर पर बांटा जाता है:
डेटा टाइप | ब्यौरा |
---|---|
स्ट्रक्चर और क्लास |
|
यूनियन |
|
एनोटेशन |
|
ग्लोबल सिंबल |
|
* सार्वजनिक और निजी सदस्य फ़ंक्शन, दोनों को बदलना या हटाना नहीं चाहिए, क्योंकि सार्वजनिक इनलाइन फ़ंक्शन निजी सदस्य फ़ंक्शन के बारे में बता सकते हैं. निजी सदस्य फ़ंक्शन के सिंबल रेफ़रंस को कॉलर बाइनरी में रखा जा सकता है. शेयर की गई लाइब्रेरी से, प्राइवेट मेंबर फ़ंक्शन को बदलने या हटाने की वजह से, पुराने सिस्टम के साथ काम नहीं करने वाली बाइनरी बन सकती हैं.
** सार्वजनिक या निजी डेटा के सदस्यों के ऑफ़सेट में बदलाव नहीं किया जाना चाहिए, क्योंकि इनलाइन फ़ंक्शन अपने फ़ंक्शन बॉडी में इन डेटा के सदस्यों का रेफ़रंस दे सकते हैं. डेटा मेंबर के ऑफ़सेट बदलने से, पुराने सिस्टम के साथ काम न करने वाली बाइनरी बन सकती हैं.
*** हालांकि, इनसे इस तरह के मेमोरी लेआउट में बदलाव नहीं होता, लेकिन सिमेंटिक अंतर हो सकता है. इसकी वजह से हो सकता है कि लाइब्रेरी उम्मीद के मुताबिक काम न करें.
एबीआई के नियमों का पालन करने वाले टूल इस्तेमाल करें
जब कोई VNDK लाइब्रेरी बनाई जाती है, तो लाइब्रेरी के एबीआई की तुलना, VNDK के उस वर्शन के एबीआई रेफ़रंस से की जाती है जिसे बनाया जा रहा है. रेफ़रंस एबीआई डंप यहां मौजूद हैं:
${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/<PLATFORM_VNDK_VERSION>/<BINDER_BITNESS>/<ARCH>/source-based
उदाहरण के लिए, एपीआई लेवल 27 पर x86 के लिए libfoo
बनाने पर, libfoo
के अनुमानित एबीआई की तुलना, यहां दी गई उसके रेफ़रंस से की जाती है:
${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/27/64/x86/source-based/libfoo.so.lsdump
एबीआई के काम न करने की गड़बड़ी
एबीआई के गड़बड़ होने पर, बिल्ड लॉग में चेतावनियां दिखती हैं. इनमें चेतावनी के टाइप के साथ-साथ,
abi-diff रिपोर्ट का पाथ भी दिखता है. उदाहरण के लिए, अगर libbinder
के एबीआई में ऐसा बदलाव किया गया है जो काम नहीं करता, तो बिल्ड सिस्टम गड़बड़ी का मैसेज दिखाता है. यह मैसेज कुछ ऐसा होता है:
***************************************************** 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 लाइब्रेरी के एबीआई की जांच करना
VNDK लाइब्रेरी बनाने पर:
header-abi-dumper
, वीएनडीके लाइब्रेरी (लाइब्रेरी की अपनी सोर्स फ़ाइलें और स्टैटिक ट्रांज़िटिव डिपेंडेंसी से इनहेरिट की गई सोर्स फ़ाइलें) बनाने के लिए, इकट्ठा की गई सोर्स फ़ाइलों को प्रोसेस करता है. इससे हर सोर्स से जुड़ी.sdump
फ़ाइलें बनाई जाती हैं.
पहला डायग्राम. .sdump
फ़ाइलें बनाई जा रही हैं- इसके बाद,
header-abi-linker
.sdump
फ़ाइलों को प्रोसेस करता है. इसके लिए, उसे दी गई वर्शन स्क्रिप्ट या शेयर की गई लाइब्रेरी से जुड़ी.so
फ़ाइल का इस्तेमाल किया जाता है. इससे.lsdump
फ़ाइल बनती है, जिसमें शेयर की गई लाइब्रेरी से जुड़ी एबीआई की सारी जानकारी लॉग होती है.
दूसरी इमेज. .lsdump
फ़ाइल बनाना header-abi-diff
,.lsdump
फ़ाइल की तुलना, रेफ़रंस.lsdump
फ़ाइल से करता है. इससे, दोनों लाइब्रेरी के एबीआई में अंतर की जानकारी देने वाली डिफ़रेंस रिपोर्ट बनती है.
तीसरी इमेज. अंतर की रिपोर्ट बनाना
हेडर-ऐबी-डंपर
header-abi-dumper
टूल, C/C++ सोर्स फ़ाइल को पार्स करता है और उस सोर्स फ़ाइल से अनुमानित एबीआई को किसी इंटरमीडिएट फ़ाइल में डाल देता है. बिल्ड सिस्टम, सभी कंपाइल की गई सोर्स फ़ाइलों पर header-abi-dumper
चलाता है. साथ ही, एक लाइब्रेरी भी बनाता है, जिसमें ट्रांज़िटिव डिपेंडेंसी की सोर्स फ़ाइलें शामिल होती हैं.
इनपुट |
|
---|---|
आउटपुट | यह एक ऐसी फ़ाइल है जिसमें सोर्स फ़ाइल के एबीआई के बारे में बताया गया है. उदाहरण के लिए,
foo.sdump , foo.cpp के एबीआई को दिखाता है.
|
फ़िलहाल, .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; }
header-abi-dumper
का इस्तेमाल करके, इंटरमीडिएट .sdump
फ़ाइल जनरेट की जा सकती है. यह फ़ाइल, सोर्स फ़ाइल से मिले एबीआई की जानकारी देती है. इसके लिए, इनका इस्तेमाल किया जा सकता है:
$ header-abi-dumper foo.cpp -I exported -o foo.sdump -- -I exported -x c++
यह निर्देश header-abi-dumper
को --
के बाद मौजूद कंपाइलर फ़्लैग के साथ foo.cpp
को पार्स करने के लिए कहता है. साथ ही, exported
डायरेक्ट्री में मौजूद सार्वजनिक हेडर से एक्सपोर्ट की गई एबीआई जानकारी को उत्सर्जित करता है. यहां दिया गया foo.sdump
, header-abi-dumper
से जनरेट किया गया है:
{ "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
में, सोर्स फ़ाइल
foo.cpp
से एक्सपोर्ट की गई एबीआई जानकारी और सार्वजनिक हेडर शामिल होते हैं. उदाहरण के लिए,
record_types
. सार्वजनिक हेडर में बताए गए स्ट्रक्चर, यूनियन या क्लास देखें. हर रिकॉर्ड टाइप में फ़ील्ड, साइज़, ऐक्सेस की खास जानकारी, फ़ाइल के बारे में जानकारी देने वाली हेडर फ़ाइल, और अन्य एट्रिब्यूट की जानकारी होती है.pointer_types
. पब्लिक हेडर में, एक्सपोर्ट किए गए रिकॉर्ड/फ़ंक्शन के ज़रिए सीधे/अप्रत्यक्ष रूप से रेफ़र किए गए पॉइंटर टाइप के साथ-साथ, उस टाइप के बारे में जानकारी दें जिस पर पॉइंटर (type_info
मेंreferenced_type
फ़ील्ड के ज़रिए) पॉइंट करता है. इसी तरह की जानकारी, क्वालीफ़ाइड टाइप, पहले से मौजूद C/C++ टाइप, ऐरे टाइप, और lvalue और rvalue रेफ़रंस टाइप के लिए.sdump
फ़ाइल में लॉग की जाती है. इस जानकारी की मदद से, बार-बार अंतर का पता लगाया जा सकता है.functions
. सार्वजनिक हेडर से एक्सपोर्ट किए गए फ़ंक्शन दिखाएं. इनमें फ़ंक्शन के बदले गए नाम, रिटर्न टाइप, पैरामीटर के टाइप, ऐक्सेस की खास जानकारी, और अन्य एट्रिब्यूट की जानकारी भी होती है.
header-abi-linker
header-abi-linker
टूल, header-abi-dumper
से बनाई गई इंटरमीडिएट फ़ाइलों को इनपुट के तौर पर
लेकर उन फ़ाइलों को लिंक करता है:
इनपुट |
|
---|---|
आउटपुट | ऐसी फ़ाइल जो किसी शेयर की गई लाइब्रेरी के एबीआई के बारे में बताती है. उदाहरण के लिए, libfoo.so.lsdump , libfoo के एबीआई को दिखाता है.
|
यह टूल, ट्रांसलेशन यूनिट के बीच के अंतर को ध्यान में रखते हुए, ट्रांसलेशन यूनिट में मौजूद सभी इंटरमीडियरी फ़ाइलों में टाइप ग्राफ़ को मर्ज करता है. यह अंतर, एक ही परिभाषा (अलग-अलग ट्रांसलेशन यूनिट में उपयोगकर्ता के तय किए गए टाइप, एक ही पूरी तरह से सही नाम के साथ, अलग-अलग अर्थ के हो सकते हैं) से जुड़ा हो सकता है. इसके बाद, टूल, एक्सपोर्ट किए गए सिंबल की सूची बनाने के लिए,
वर्शन स्क्रिप्ट या शेयर की गई लाइब्रेरी (.so
फ़ाइल) की .dynsym
टेबल को पार्स करता है.
उदाहरण के लिए, libfoo
में foo.cpp
और
bar.cpp
शामिल हैं. libfoo
का पूरा लिंक किया गया एबीआई डंप बनाने के लिए, 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
टूल:
- यह डायरेक्ट्री में मौजूद हेडर में मौजूद ABI जानकारी को फ़िल्टर करके,
.sdump
फ़ाइलों (foo.sdump
औरbar.sdump
) को लिंक करता है.exported
libfoo.so
को पार्स करता है और लाइब्रेरी की.dynsym
टेबल के ज़रिए, एक्सपोर्ट किए गए सिंबल के बारे में जानकारी इकट्ठा करता है.- इसमें
_Z3FooiP3bar
और_Z6FooBadiP3foo
जोड़े जाते हैं.
libfoo.so.lsdump
, libfoo.so
का जनरेट किया गया आखिरी एबीआई डंप है.
header-abi-diff
header-abi-diff
टूल, दो लाइब्रेरी के एबीआई को दिखाने वाली दो .lsdump
फ़ाइलों की तुलना करता है. साथ ही, दोनों एबीआई के बीच के अंतर की जानकारी देने वाली एक डिफ़रेंस रिपोर्ट बनाता है.
इनपुट |
|
---|---|
आउटपुट | तुलना की गई दो शेयर की गई लाइब्रेरी के एबीआई में अंतर बताने वाली डिफ़रेंस रिपोर्ट. |
एबीआई की डिफ़रेंस फ़ाइल, प्रोटोबस टेक्स्ट फ़ॉर्मैट में हो. आने वाले समय में, इस फ़ॉर्मैट में बदलाव हो सकता है.
उदाहरण के लिए, आपके पास libfoo
के दो वर्शन हैं: libfoo_old.so
और libfoo_new.so
. libfoo_new.so
में,
bar_t
में, mfoo
के टाइप को
foo_t
से बदलकर foo_t *
किया जाता है. bar_t
एक ऐसा टाइप है जिसे ऐक्सेस किया जा सकता है. इसलिए, इसे header-abi-diff
के ज़रिए, एबीआई में बदलाव करने वाले बदलाव के तौर पर फ़्लैग किया जाना चाहिए.
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
में एबीआई के सभी बदलावों की रिपोर्ट होती है. record_type_diffs
मैसेज से पता चलता है कि किसी रिकॉर्ड में बदलाव हुआ है. साथ ही, इसमें ऐसे बदलावों की सूची भी होती है जो काम नहीं करते. इनमें ये शामिल हैं:
- रिकॉर्ड का साइज़,
24
बाइट से8
बाइट में बदल रहा है. mfoo
फ़ील्ड का टाइप,foo
से बदलकरfoo *
हो गया है (सभी typedef हटा दिए गए हैं).
type_stack
फ़ील्ड से पता चलता है कि header-abi-diff
कैसे बदले गए टाइप (bar
) तक पहुंचा. इस फ़ील्ड को इस तरह समझा जा सकता है कि Foo
एक एक्सपोर्ट किया गया फ़ंक्शन है, जो पैरामीटर के तौर पर bar *
लेता है. यह bar
पर ले जाता है, जिसे एक्सपोर्ट किया गया था और बदला गया था.
एबीआई और एपीआई लागू करना
VNDK की शेयर की गई लाइब्रेरी के एबीआई और एपीआई को लागू करने के लिए, एबीआई रेफ़रंस को ${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/
में चेक इन करना ज़रूरी है.
ये रेफ़रंस बनाने के लिए, यह कमांड चलाएं:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py
रेफ़रंस बनाने के बाद, सोर्स कोड में किया गया कोई भी बदलाव, VNDK लाइब्रेरी में ABI/API में बदलाव के साथ काम नहीं करता. इस वजह से, अब बिल्ड करने में गड़बड़ी होती है.
किसी खास लाइब्रेरी के लिए एबीआई रेफ़रंस अपडेट करने के लिए, यह कमांड चलाएं:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l <lib1> -l <lib2>
उदाहरण के लिए, libbinder
एबीआई के रेफ़रंस अपडेट करने के लिए, इसे चलाएं:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l libbinder