ABI-Stabilität

Die Stabilität der Application Binary Interface (ABI) ist eine Voraussetzung für Nur Framework-Updates, da Anbietermodule möglicherweise vom nativen System des Anbieters abhängen Gemeinsam genutzte Bibliotheken des Development Kits (VNDK), die sich in der Systempartition befinden. Innerhalb eines Android-Release müssen neu erstellte gemeinsam genutzte VNDK-Bibliotheken ABI-kompatibel mit zuvor veröffentlichten VNDK-Bibliotheken, sodass Anbietermodule mit diesen Bibliotheken ohne Neukompilierung und ohne Laufzeitfehler arbeiten. Zwischen Android-Releases können VNDK-Bibliotheken geändert werden und es gibt kein ABI. Garantien.

Um die ABI-Kompatibilität sicherzustellen, umfasst Android 9 ABI-Header-Prüfung, wie in den folgenden Abschnitten beschrieben.

VNDK- und ABI-Compliance

Das VNDK ist ein restriktiver Satz von Bibliotheken, mit denen Anbietermodule verknüpft werden können. die reine Framework-Updates ermöglichen. Die ABI-Konformität bezieht sich auf die eine neuere Version einer gemeinsam genutzten Bibliothek mit einem -Modul, das dynamisch verknüpft ist (d.h. als ältere Version des Bibliothek).

Exportierte Symbole

Ein exportiertes Symbol (auch als globales Symbol bezeichnet) bezieht sich auf ein Symbol, das alle folgenden Anforderungen erfüllt:

  • Sie werden über die öffentlichen Header einer gemeinsam genutzten Bibliothek exportiert.
  • Erscheint in der Tabelle .dynsym der Datei .so die der gemeinsam genutzten Bibliothek entspricht.
  • Die Bindung hat SCHWACH oder GLOBALE.
  • Die Sichtbarkeit ist STANDARD oder GESCHÜTZT.
  • Abschnittsindex ist nicht UNEFFEKT.
  • Der Typ ist entweder FUNC oder OBJECT.

Die öffentlichen Header einer gemeinsam genutzten Bibliothek sind als Header definiert. für andere Bibliotheken/Binärprogramme über die export_include_dirs, export_header_lib_headers, export_static_lib_headers, export_shared_lib_headers und Attribute vom Typ export_generated_headers in Android.bp des Moduls für die gemeinsam genutzte Bibliothek.

Erreichbare Typen

Ein erreichbarer Typ ist jeder integrierte oder benutzerdefinierte C/C++-Typ, der direkt oder indirekt über ein exportiertes Symbol erreichbar UND exportiert über öffentliche Header. Beispiel: libfoo.so hat die Funktion Foo, ein exportiertes Symbol aus der .dynsym. Die libfoo.so-Bibliothek enthält Folgendes: Folgendes:

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-Tabelle
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

Zu den direkt/indirekt erreichbaren Typen von Foo gehören:

Typ Beschreibung
bool Rückgabetyp von Foo.
int Typ des ersten Foo-Parameters.
bar_t * Typ des zweiten Foo-Parameters. Bis zum bar_t *, bar_t wird über foo_exported.h exportiert.

bar_t enthält ein Mitglied mfoo vom Typ foo_t, das über foo_exported.h exportiert wird, Dadurch werden weitere Typen exportiert:
    .
  • int : ist der Typ von m1.
  • int * : ist der Typ von m2.
  • foo_private_t * : ist der Typ von mPfoo.

foo_private_t ist jedoch NICHT erreichbar, exportiert über foo_exported.h. (foo_private_t *) ist opak, daher sind Änderungen an foo_private_t zulässig.)

Eine ähnliche Erklärung kann für Typen gegeben werden, die über die Basisklasse erreichbar sind auch Spezifizierer und Vorlagenparameter.

ABI-Konformität sicherstellen

Für die gekennzeichneten Bibliotheken muss die ABI-Konformität sichergestellt werden. vendor_available: true und vndk.enabled: true im entsprechende Android.bp-Dateien. Beispiel:

cc_library {
    name: "libvndk_example",
    vendor_available: true,
    vndk: {
        enabled: true,
    }
}

Bei Datentypen, die direkt oder indirekt über eine exportierte Funktion erreichbar sind, gilt der Wert Die folgenden Änderungen an einer Bibliothek werden als ABI-absteigend eingestuft:

Datentyp Beschreibung
Strukturen und Klassen
  • Größe des Klassentyps oder Strukturtyps ändern
  • Basisklassen <ph type="x-smartling-placeholder">
      </ph>
    • Basisklassen hinzufügen oder entfernen
    • Sie können praktisch übernommene Basisklassen hinzufügen oder entfernen.
    • Ändern Sie die Reihenfolge der Basisklassen.
  • Mitgliedsfunktionen <ph type="x-smartling-placeholder">
      </ph>
    • Mitgliedsfunktionen entfernen*
    • Argumente von Mitgliederfunktionen hinzufügen oder daraus entfernen
    • Argumenttypen oder Rückgabetypen von „member“ ändern Funktionen*.
    • Layout der virtuellen Tabelle ändern
  • Datenmitglieder <ph type="x-smartling-placeholder">
      </ph>
    • Entfernen Sie statische Datenmitglieder.
    • Fügen Sie nicht statische Datenmitglieder hinzu oder entfernen Sie sie.
    • Ändern Sie die Typen der Datenmitglieder.
    • Ändern Sie die Offsets auf nicht statische Datenmitglieder**.
    • const, volatile und/oder restricted-Qualifier für Datenmitglieder***.
    • Führen Sie ein Downgrade der Zugriffsspezifizierer von Datenmitgliedern aus***.
  • Ändern Sie die Vorlagenargumente.
Gewerkschaften
  • Datenmitglieder hinzufügen oder entfernen
  • Ändern Sie die Größe des Union-Typs.
  • Ändern Sie die Typen der Datenmitglieder.
Aufzählungen
  • Ändern Sie den zugrunde liegenden Typ.
  • Ändern Sie die Namen der Zähler.
  • Ändern Sie die Werte der Zähler.
Globale Symbole
  • Entfernen Sie die von öffentlichen Headern exportierten Symbole.
  • Für globale Symbole vom Typ FUNC <ph type="x-smartling-placeholder">
      </ph>
    • Fügen Sie Argumente hinzu oder entfernen Sie sie.
    • Ändern Sie die Argumenttypen.
    • Ändern Sie den Rückgabetyp.
    • Führen Sie ein Downgrade für den Zugriffsspezifizierer*** aus.
  • Für globale Symbole vom Typ OBJECT <ph type="x-smartling-placeholder">
      </ph>
    • Ändern Sie den entsprechenden C/C++-Typ.
    • Führen Sie ein Downgrade für den Zugriffsspezifizierer*** aus.

* Sowohl öffentliche als auch private Mitgliedsfunktionen müssen geändert oder entfernt werden, da öffentliche Inline-Funktionen auf private Member-Funktionen. Symbolverweise auf Funktionen für private Mitglieder in den Binärdateien der Aufrufer gespeichert werden. Funktionen für private Mitglieder ändern oder entfernen aus gemeinsam genutzten Bibliotheken können zu nicht abwärtskompatiblen Binärprogrammen führen.

** Die Offsets für öffentliche oder private Datenmitglieder dürfen geändert, da Inline-Funktionen in ihrem Funktionstext. Wenn Sie Offsets für Datenelemente ändern, kann dies zu nicht abwärtskompatible Binärdateien.

*** Das Arbeitsspeicher-Layout wird dadurch nicht geändert. gibt es semantische Unterschiede, die dazu führen können, dass Bibliotheken und wie erwartet funktioniert.

ABI-Compliance-Tools verwenden

Beim Erstellen einer VNDK-Bibliothek wird das ABI der Bibliothek mit dem entsprechende ABI-Referenz für die Version des VNDK, das erstellt wird. Nachschlagewerke Hier findest du die ABI-Dumps:

${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/<PLATFORM_VNDK_VERSION>/<BINDER_BITNESS>/<ARCH>/source-based

Wenn Sie beispielsweise libfoo für x86 auf API-Ebene 27 erstellen, Das abgeleitete ABI von libfoo wird mit der Referenz hier verglichen:

${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/27/64/x86/source-based/libfoo.so.lsdump

ABI-Ausfallfehler

Bei ABI-Fehlern werden im Build-Log Warnungen mit dem Warntyp und einer zum Bericht „abi-diff“. Wenn das ABI von libbinder beispielsweise nicht kompatibel ist, gibt das Build-System einen Fehler mit einer Meldung etwa so:

*****************************************************
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 ----

ABI-Prüfungen der VNDK-Bibliothek erstellen

Wenn eine VNDK-Bibliothek erstellt wird:

  1. header-abi-dumper verarbeitet die zu kompilierten Quelldateien die VNDK-Bibliothek erstellen (eigene Quelldateien und -dateien der Bibliothek) die über statische transitive Abhängigkeiten übernommen werden), .sdump-Dateien, die der jeweiligen Quelle entsprechen.
    Sdump-Erstellung
    Abbildung 1: .sdump erstellen Dateien
  2. header-abi-linker verarbeitet dann .sdump -Dateien (mit einem Versionsskript oder dem .so entsprechenden Datei der gemeinsam genutzten Bibliothek), um ein .lsdump-Objekt zu erstellen. -Datei, in der alle ABI-Informationen protokolliert werden, die der gemeinsam genutzten Bibliothek entsprechen.
    lsdump-erstellung
    Abbildung 2: .lsdump erstellen Datei
  3. header-abi-diff vergleicht die .lsdump Datei mit einer .lsdump-Referenzdatei zum Erstellen eines Differenzberichts in dem die Unterschiede zwischen den ABIs der beiden Bibliotheken beschrieben werden.
    Abi-Unterschiede erstellen
    Abbildung 3: Bericht „Unterschiede“ erstellen

Header-Abi-Dump

Das header-abi-dumper-Tool parst eine C/C++-Quelldatei und speichert sie aus die aus dieser Quelldatei abgeleitete ABI in eine Zwischendatei. Der Build führt das System header-abi-dumper für alle kompilierten Quelldateien aus, während Erstellen einer Bibliothek, die die Quelldateien aus transitiven Abhängigkeiten.

Eingänge
  • Eine C/C++-Quelldatei
  • Exportierte „Einschließen“-Verzeichnisse
  • Compiler-Flags
Ausgabe Eine Datei, die die ABI der Quelldatei beschreibt (z. B. foo.sdump für das ABI von foo.cpp steht).

Derzeit liegen .sdump-Dateien im JSON-Format vor, das nicht und bleibt auch bei zukünftigen Releases stabil. Daher .sdump sollte als Details zur Implementierung des Build-Systems betrachtet werden.

libfoo.so hat beispielsweise die folgende Quelldatei 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;
}

Mit header-abi-dumper können Sie eine Zwischenstufe .sdump-Datei, die das von der Quelldatei bereitgestellte ABI darstellt mit:

$ header-abi-dumper foo.cpp -I exported -o foo.sdump -- -I exported -x c++

Dieser Befehl weist header-abi-dumper an, foo.cpp mit den Compiler-Flags nach -- und die ABI-Informationen ausgeben, die von den öffentlichen Headern im exported. Folgendes ist foo.sdump generiert von 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 enthält von der Quelldatei exportierte ABI-Informationen foo.cpp und die öffentlichen Header, z. B.

  • record_types Auf definierte Strukturen, Unions oder Klassen verweisen in den öffentlichen Headern. Jeder Eintragstyp enthält Informationen zu den Feldern, Größe, Zugriffsbezeichner, der Headerdatei, in der es definiert ist, Attribute.
  • pointer_types Direkt/indirekt auf Zeigertypen verweisen in den öffentlichen Headern durch die exportierten Datensätze/Funktionen referenziert wird, sowie durch den Typ, auf den der Zeiger verweist (über die referenced_type in type_info. Ähnliche Informationen werden im .sdump-Datei für qualifizierte Typen, integrierte C/C++-Typen, Array - und l-Wert- und r-Wert-Referenztypen. Diese Informationen können rekursive Differenz.
  • functions Stellt Funktionen dar, die durch öffentliche Header exportiert wurden. Sie enthalten auch Informationen über den gekürzten Namen der Funktion, den Rückgabetyp, die Parametertypen, den Zugriffsbezeichner und andere Attribute.
<ph type="x-smartling-placeholder">

Header-Abi-Linker

Das header-abi-linker-Tool nimmt die erstellten Zwischendateien durch header-abi-dumper als Eingabe und verknüpft dann diese Dateien:

Eingänge
  • Von header-abi-dumper erstellte Zwischendateien
  • Versionsskript/Map-Datei (optional)
  • .so Datei der gemeinsam genutzten Bibliothek
  • Exportierte „Einschließen“-Verzeichnisse
Ausgabe Eine Datei, die die ABI einer gemeinsam genutzten Bibliothek beschreibt (z. B. libfoo.so.lsdump für das ABI von libfoo steht).

Das Tool führt die Typendiagramme in allen ihm übergebenen Zwischendateien zusammen, unter Berücksichtigung einer Definition (benutzerdefinierte Typen in unterschiedlichen Übersetzungseinheiten mit demselben voll qualifizierten Namen, könnten semantisch Unterschiede zwischen Übersetzungseinheiten. Das Tool parst entweder ein Versionsskript oder die Tabelle .dynsym der gemeinsam genutzten Bibliothek (Datei .so), um eine Liste der exportierten Symbole zu erstellen.

libfoo besteht beispielsweise aus foo.cpp und bar.cpp header-abi-linker könnte aufgerufen werden für Erstellen Sie den vollständigen verknüpften ABI-Dump von libfoo so:

header-abi-linker -I exported foo.sdump bar.sdump \
                  -o libfoo.so.lsdump \
                  -so libfoo.so \
                  -arch arm64 -api current

Beispiel für die Befehlsausgabe in 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" : []
}

Das header-abi-linker-Tool:

  • Verknüpft die bereitgestellten .sdump-Dateien (foo.sdump) und bar.sdump). Dabei werden die ABI-Informationen herausgefiltert, die nicht in die Header im Verzeichnis exported.
  • Parst libfoo.so und erfasst Informationen zu den Symbolen von der Bibliothek über ihre Tabelle .dynsym exportiert wurde.
  • Fügt _Z3FooiP3bar und _Z6FooBadiP3foo hinzu.

libfoo.so.lsdump ist der abschließend generierte ABI-Dump von libfoo.so.

Header-abi-diff

Das header-abi-diff-Tool vergleicht zwei .lsdump-Dateien die das ABI von zwei Bibliotheken repräsentiert, und erstellt einen Differenzbericht, aus dem hervorgeht, Unterschiede zwischen den beiden ABIs.

Eingänge
  • .lsdump-Datei, die das ABI einer alten freigegebenen Datei darstellt Bibliothek.
  • Datei .lsdump, die die ABI einer neuen gemeinsam genutzten Bibliothek darstellt.
Ausgabe Einen Diff-Bericht, der die Unterschiede zwischen den von den beiden angebotenen ABIs ausgibt gemeinsam genutzten Bibliotheken verglichen werden.

Die ABI-Differenzdatei befindet sich in <ph type="x-smartling-placeholder"></ph> protobuf-Textformat. Das Format kann sich ändern. in zukünftigen Versionen.

Sie haben beispielsweise zwei Versionen libfoo: libfoo_old.so und libfoo_new.so Im libfoo_new.so, in bar_t, Sie ändern den Typ von mfoo von foo_t bis foo_t *. Da bar_t ein erreichbar sind, sollte dies als funktionsgefährdende Änderung header-abi-diff.

So führen Sie header-abi-diff aus:

header-abi-diff -old libfoo_old.so.lsdump \
                -new libfoo_new.so.lsdump \
                -arch arm64 \
                -o libfoo.so.abidiff \
                -lib libfoo

Beispiel für die Befehlsausgabe in 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 enthält einen Bericht über alle ABI-Probleme Änderungen bei libfoo. Die record_type_diffs-Nachricht zeigt an, dass ein Datensatz geändert wurde, und listet die inkompatiblen Änderungen auf, die umfassen:

  • Die Größe des Eintrags ändert sich von 24 Byte in 8 Byte.
  • Der Feldtyp von mfoo ändert sich von foo zu foo * (alle Typedefs werden entfernt).

Das Feld type_stack gibt an, wie header-abi-diff hat den Typ erreicht, der sich geändert hat (bar). Dieses Feld kann interpretiert als Foo ist eine exportierte Funktion, bar * als Parameter, der auf bar verweist, was exportiert und geändert werden.

<ph type="x-smartling-placeholder">

ABI und API erzwingen

Um die ABI und API von gemeinsam genutzten VNDK-Bibliotheken zu erzwingen, müssen ABI-Referenzen bei ${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/ eingecheckt werden. Führen Sie den folgenden Befehl aus, um diese Referenzen zu erstellen:

${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py

Nach dem Erstellen der Verweise: alle Änderungen am Quellcode, die sich daraus ergeben in einer inkompatiblen ABI/API-Änderung in einer VNDK-Bibliothek führt jetzt zu einem Build-Fehler.

Führen Sie den folgenden Befehl aus, um ABI-Referenzen für bestimmte Bibliotheken zu aktualisieren:

${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l <lib1> -l <lib2>

Führen Sie beispielsweise folgenden Befehl aus, um libbinder ABI-Referenzen zu aktualisieren:

${ANDROID_BUILD_TOP}/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l libbinder