एप्लिकेशन बाइनरी इंटरफ़ेस (एबीआई) स्थिरता फ्रेमवर्क-केवल अपडेट की एक शर्त है क्योंकि विक्रेता मॉड्यूल सिस्टम विभाजन में रहने वाले विक्रेता मूल विकास किट (वीएनडीके) साझा पुस्तकालयों पर निर्भर हो सकते हैं। एंड्रॉइड रिलीज़ के भीतर, नव-निर्मित VNDK साझा लाइब्रेरीज़ को पहले रिलीज़ की गई VNDK साझा लाइब्रेरीज़ के लिए ABI-संगत होना चाहिए ताकि विक्रेता मॉड्यूल उन लाइब्रेरीज़ के साथ बिना पुनर्संकलन और रनटाइम त्रुटियों के काम कर सकें। एंड्रॉइड रिलीज़ के बीच, VNDK लाइब्रेरीज़ को बदला जा सकता है और कोई ABI गारंटी नहीं है।
एबीआई अनुकूलता सुनिश्चित करने में मदद के लिए, एंड्रॉइड 9 में एक हेडर एबीआई चेकर शामिल है, जैसा कि निम्नलिखित अनुभागों में बताया गया है।
वीएनडीके और एबीआई अनुपालन के बारे में
वीएनडीके पुस्तकालयों का एक प्रतिबंधात्मक सेट है जिसे विक्रेता मॉड्यूल लिंक कर सकते हैं और जो केवल फ्रेमवर्क अपडेट को सक्षम करते हैं। एबीआई अनुपालन एक साझा लाइब्रेरी के नए संस्करण की उस मॉड्यूल के साथ अपेक्षित रूप से काम करने की क्षमता को संदर्भित करता है जो गतिशील रूप से इससे जुड़ा हुआ है (यानी लाइब्रेरी के पुराने संस्करण के रूप में काम करता है)।
निर्यातित प्रतीकों के बारे में
एक निर्यातित प्रतीक (जिसे वैश्विक प्रतीक के रूप में भी जाना जाता है) एक ऐसे प्रतीक को संदर्भित करता है जो निम्नलिखित सभी को संतुष्ट करता है:
- साझा लाइब्रेरी के सार्वजनिक शीर्षलेखों द्वारा निर्यात किया गया।
- साझा लाइब्रेरी के अनुरूप
.so
फ़ाइल की.dynsym
तालिका में दिखाई देता है। - कमजोर या वैश्विक बंधन है।
- दृश्यता डिफ़ॉल्ट या संरक्षित है.
- अनुभाग सूचकांक अपरिभाषित नहीं है.
- प्रकार या तो 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.बीपी |
---|
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 * | दूसरे फू पैरामीटर का प्रकार। 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 लाइब्रेरी बनाई जाती है, तो लाइब्रेरी के ABI की तुलना VNDK के बनाए जा रहे संस्करण के लिए संबंधित ABI संदर्भ से की जाती है। संदर्भ एबीआई डंप यहां स्थित हैं:
${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/<PLATFORM_VNDK_VERSION>/<BINDER_BITNESS>/<ARCH>/source-based
उदाहरण के लिए, एपीआई स्तर 27 पर x86 के लिए libfoo
निर्माण पर, libfoo
के अनुमानित ABI की तुलना इसके संदर्भ से की जाती है:
${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/27/64/x86/source-based/libfoo.so.lsdump
एबीआई टूटने की त्रुटि
एबीआई टूटने पर, बिल्ड लॉग चेतावनी प्रकार और एबीआई-डिफ रिपोर्ट के पथ के साथ चेतावनियां प्रदर्शित करता है। उदाहरण के लिए, यदि 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 लाइब्रेरी बनाई जाती है:
-
header-abi-dumper
VNDK लाइब्रेरी (लाइब्रेरी की अपनी स्रोत फ़ाइलों के साथ-साथ स्थैतिक ट्रांजिटिव निर्भरता के माध्यम से विरासत में मिली स्रोत फ़ाइलों) के निर्माण के लिए संकलित स्रोत फ़ाइलों को संसाधित करता है, ताकि प्रत्येक स्रोत के अनुरूप.sdump
फ़ाइलों का उत्पादन किया जा सके।चित्र 1. .sdump
फ़ाइलें बनाना -
header-abi-linker
फिर.sdump
फ़ाइल बनाने के लिए.lsdump
फ़ाइलों (या तो इसे प्रदान की गई संस्करण स्क्रिप्ट या साझा लाइब्रेरी से संबंधित.so
फ़ाइल का उपयोग करके) को संसाधित करता है जो साझा लाइब्रेरी से संबंधित सभी ABI जानकारी को लॉग करता है।चित्र 2. .lsdump
फ़ाइल बनाना -
header-abi-diff
एक भिन्न रिपोर्ट तैयार करने के लिए.lsdump
फ़ाइल की तुलना संदर्भ.lsdump
फ़ाइल से करता है जो दो पुस्तकालयों के एबीआई में अंतर को रेखांकित करता है।चित्र 3. भिन्न रिपोर्ट बनाना
हेडर-अबी-डम्पर
header-abi-dumper
टूल एक सी/सी++ स्रोत फ़ाइल को पार्स करता है और उस स्रोत फ़ाइल से अनुमानित एबीआई को एक मध्यवर्ती फ़ाइल में डंप करता है। बिल्ड सिस्टम सभी संकलित स्रोत फ़ाइलों पर 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
उपयोग कर सकते हैं जो स्रोत फ़ाइल द्वारा प्रस्तुत एबीआई का प्रतिनिधित्व करता है:
$ header-abi-dumper foo.cpp -I exported -o foo.sdump -- -I exported -x c++
यह कमांड header-abi-dumper
निम्नलिखित कंपाइलर फ़्लैग के साथ foo.cpp
पार्स करने के लिए कहता है --
और 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
में स्रोत फ़ाइल foo.cpp
और सार्वजनिक हेडर द्वारा निर्यात की गई ABI जानकारी शामिल है, उदाहरण के लिए,
-
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 का प्रतिनिधित्व करती है)। |
उपकरण इसे दी गई सभी मध्यवर्ती फ़ाइलों में प्रकार ग्राफ़ को मर्ज करता है, अनुवाद इकाइयों में एक-परिभाषा (एक ही पूर्णतः योग्य नाम के साथ विभिन्न अनुवाद इकाइयों में उपयोगकर्ता-परिभाषित प्रकार, शब्दार्थ रूप से भिन्न हो सकते हैं) को ध्यान में रखता है। उपकरण तब निर्यात किए गए प्रतीकों की एक सूची बनाने के लिए या तो एक संस्करण स्क्रिप्ट या साझा लाइब्रेरी ( .so
फ़ाइल) की .dynsym
तालिका को पार्स करता है।
उदाहरण के लिए, libfoo
में foo.cpp
और bar.cpp
शामिल हैं। header-abi-linker
निम्नानुसार libfoo
के पूर्ण लिंक किए गए एबीआई डंप को बनाने के लिए लागू किया जा सकता है:
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
टूल दो पुस्तकालयों के एबीआई का प्रतिनिधित्व करने वाली दो .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
में सभी ABI ब्रेकिंग परिवर्तनों की एक रिपोर्ट शामिल है। record_type_diffs
संदेश इंगित करता है कि रिकॉर्ड बदल गया है और असंगत परिवर्तनों को सूचीबद्ध करता है, जिसमें शामिल हैं:
- रिकॉर्ड का आकार
24
बाइट्स से8
बाइट्स में बदल रहा है। -
mfoo
का फ़ील्ड प्रकारfoo
सेfoo *
में बदल रहा है (सभी टाइपडिफ़ हटा दिए गए हैं)।
type_stack
फ़ील्ड इंगित करता है कि header-abi-diff
उस प्रकार तक कैसे पहुंचा जो बदल गया ( bar
)। इस फ़ील्ड की व्याख्या इस प्रकार की जा सकती है कि Foo
एक निर्यातित फ़ंक्शन है जो bar *
को पैरामीटर के रूप में लेता है, जो bar
की ओर इंगित करता है, जिसे निर्यात किया गया था और बदल दिया गया था।
एबीआई/एपीआई लागू करना
VNDK साझा पुस्तकालयों के ABI/API को लागू करने के लिए, ABI संदर्भों ${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/
में जांचना होगा। इन संदर्भों को बनाने के लिए, निम्न आदेश चलाएँ:
${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py
संदर्भ बनाने के बाद, स्रोत कोड में किए गए किसी भी बदलाव के परिणामस्वरूप वीएनडीके लाइब्रेरी में असंगत एबीआई/एपीआई परिवर्तन होता है, जिसके परिणामस्वरूप अब बिल्ड त्रुटि होती है।
विशिष्ट पुस्तकालयों के लिए एबीआई संदर्भों को अद्यतन करने के लिए, निम्नलिखित आदेश चलाएँ:
${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