ABI kararlılığı

Tedarikçi firma modülleri, sistem bölümünde bulunan Tedarikçi Yerel Geliştirme Kiti (VNDK) paylaşılan kitaplıklarına bağlı olabileceğinden, Uygulama İkili Arabirimi (ABI) kararlılığı, yalnızca çerçeve güncellemelerinin ön koşuludur. Android sürümünde, yeni oluşturulan VNDK paylaşılan kitaplıkları, tedarikçi modüllerinin yeniden derleme yapmadan ve çalışma zamanında hata vermeden bu kitaplıklarla çalışabilmesi için daha önce yayınlanan VNDK paylaşılan kitaplıklarıyla ABI uyumlu olmalıdır. Android sürümleri arasında VNDK kitaplıkları değiştirilebilir ve ABI garantisi yoktur.

Android 9, ABI uyumluluğunu sağlamak için aşağıdaki bölümlerde açıklandığı gibi bir başlık ABI denetleyicisi içerir.

VNDK ve ABI uyumluluğu hakkında

VNDK, tedarikçi modüllerinin bağlanabileceği ve yalnızca çerçeve güncellemelerine olanak tanıyan kısıtlayıcı bir kitaplık grubudur. ABI uyumluluğu, paylaşılan bir kitaplığın yeni sürümünün, kendisine dinamik olarak bağlı bir modülle beklendiği gibi çalışma (ör. kitaplığın eski sürümünün çalıştığı gibi çalışma) özelliğini ifade eder.

Dışa aktarılan simgeler hakkında

Dışa aktarılan simge (küresel simge olarak da bilinir), aşağıdakilerin tümünü karşılayan bir simgeyi ifade eder:

  • Paylaşılan bir kitaplığın herkese açık başlıkları tarafından dışa aktarılır.
  • Paylaşılan kitaplığa karşılık gelen .so dosyasının .dynsym tablosunda görünür.
  • WEAK veya GLOBAL bağlamaya sahiptir.
  • Görüş mesafesi VARSAYILAN veya KORUYOR.
  • Bölüm dizini UNDEFINED değil.
  • Tür, FUNC veya OBJECT olmalıdır.

Paylaşılan bir kitaplığın herkese açık üstbilgileri, paylaşılan kitaplığa karşılık gelen modülün Android.bp tanımındaki export_include_dirs, export_header_lib_headers, export_static_lib_headers, export_shared_lib_headers ve export_generated_headers özellikleri aracılığıyla diğer kitaplıklar/ikili dosyalar tarafından kullanılabilen üstbilgiler olarak tanımlanır.

Erişilebilir türler hakkında

Erişilebilir tür, doğrudan veya dolaylı olarak dışa aktarılan bir simge aracılığıyla erişilebilen VE herkese açık üstbilgiler aracılığıyla dışa aktarılan tüm C/C++ yerleşik veya kullanıcı tanımlı türlerdir. Örneğin, libfoo.so tablosunda .dynsym tablosunda bulunan ve dışa aktarılan bir simge olan Foo işlevi vardır. libfoo.so kitaplığı şunları içerir:

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 tablosu
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'e bakıldığında, doğrudan/dolaylı olarak erişilebilen türler şunlardır:

Tür Açıklama
bool Foo değerinin dönüş türü.
int İlk Foo parametresinin türü.
bar_t * İkinci Foo parametresinin türü. bar_t * aracılığıyla, bar_t foo_exported.h üzerinden dışa aktarılır.

bar_t, foo_t türüne sahip bir mfoo üyesi içerir. Bu üye, foo_exported.h üzerinden dışa aktarılır. Bu da daha fazla türün dışa aktarılmasına neden olur:
  • int :, m1 türüdür.
  • int * :, m2 türüdür.
  • foo_private_t * : , mPfoo türüdür.

Ancak foo_exported.h üzerinden dışa aktarılmadığı için foo_private_t adlı öğeye erişilemiyor. (foo_private_t * opak olduğundan foo_private_t'ta yapılan değişikliklere izin verilir.)

Temel sınıf belirteçleri ve şablon parametreleri aracılığıyla erişilebilen türler için de benzer bir açıklama verilebilir.

ABI'ye uygunluğu sağlama

İlgili Android.bp dosyalarında vendor_available: true ve vndk.enabled: true ile işaretlenmiş kitaplıklar için ABI uyumluluğu sağlanmalıdır. Örnek:

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

Dışa aktarılan bir işlev tarafından doğrudan veya dolaylı olarak erişilebilen veri türleri için kitaplıkta yapılan aşağıdaki değişiklikler ABI'yi bozan değişiklikler olarak sınıflandırılır:

Veri türü Açıklama
Yapılar ve Sınıflar
  • Sınıf türünün veya yapı türünün boyutunu değiştirin.
  • Temel sınıflar
    • Temel sınıf ekleyin veya kaldırın.
    • Sanal olarak devralınan temel sınıfları ekleyin veya kaldırın.
    • Temel sınıfların sırasını değiştirebilirsiniz.
  • Üye işlevleri
    • Üye işlevlerini kaldırın*.
    • Üye işlevlerine bağımsız değişken ekleme veya mevcut bağımsız değişkenleri kaldırma.
    • Üye işlevlerinin bağımsız değişken türlerini veya döndürülen değer türlerini değiştirebilirsiniz*.
    • Sanal tablo düzenini değiştirin.
  • Veri üyeleri
    • Statik veri üyelerini kaldırın.
    • Statik olmayan veri üyeleri ekleyin veya kaldırın.
    • Veri üyelerinin türlerini değiştirin.
    • Ofsetleri statik olmayan veri üyeleriyle değiştirin**.
    • Veri üyelerinin const, volatile ve/veya restricted niteliklerini değiştirin***.
    • Veri üyelerinin erişim belirteçlerini düşürün***.
  • Şablon bağımsız değişkenlerini değiştirin.
Birlikler
  • Veri üyeleri ekleyin veya kaldırın.
  • Birleştirme türünün boyutunu değiştirin.
  • Veri üyelerinin türlerini değiştirin.
Listeleme
  • Temel türü değiştirin.
  • Sayımcıların adlarını değiştirme
  • Listeleyicilerin değerlerini değiştirin.
Küresel Semboller
  • Herkese açık üstbilgilerle dışa aktarılan sembolleri kaldırın.
  • FUNC türündeki global semboller için
    • Parametre ekleyin veya kaldırın.
    • Bağımsız değişken türlerini değiştirin.
    • İade türünü değiştirin.
    • Erişim belirtecinin düzeyini düşürebilir***.
  • OBJECT türündeki global semboller için
    • İlgili C/C++ türünü değiştirin.
    • Erişim belirticisini düşürün***.

* Herkese açık satır içi işlevler gizli üye işlevlerine atıfta bulunabileceğinden hem herkese açık hem de gizli üye işlevleri değiştirilmemeli veya kaldırılmamalıdır. Özel üye işlevlerine yönelik simge referansları, arayan ikili dosyalarında tutulabilir. Gizli üye işlevlerinin paylaşılan kitaplıklardan değiştirilmesi veya kaldırılması, geriye dönük olarak uyumsuz ikili programlara neden olabilir.

** Satır içi işlevler işlev gövdelerinde bu veri üyelerine referans verebileceğinden, herkese açık veya özel veri üyelerinin ofsetleri değiştirilmemelidir. Veri üyesi ofsetlerinin değiştirilmesi, eski sürümlerle uyumlu olmayan ikili dosyalara neden olabilir.

*** Bunlar türün bellek düzenini değiştirmese de kitaplıkların beklendiği gibi çalışmamasına neden olabilecek anlamsal farklılıklar vardır.

ABI uygunluk araçlarını kullanma

Bir VNDK kitaplığı oluşturulduğunda kitaplığın ABI'sı, oluşturulmakta olan VNDK sürümünün karşılık gelen ABI referansıyla karşılaştırılır. Referans ABI dökümleri şu konumlarda bulunur:

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

Örneğin, API seviyesi 27'de x86 için libfoo derlenirken, libfoo'ün türetilmiş ABI'si şu referansla karşılaştırılır:

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

ABI kesinti hatası

ABI bozulmalarında, derleme günlüğünde uyarı türü ve abi-diff raporunun yolu içeren uyarılar gösterilir. Örneğin, libbinder'nin ABI'sinde uyumsuz bir değişiklik varsa derleme sistemi aşağıdakine benzer bir mesaj içeren bir hata verir:

*****************************************************
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 kitaplığı ABI kontrolleri oluşturma

Bir VNDK kitaplığı oluşturulduğunda:

  1. header-abi-dumper, VNDK kitaplığını oluşturmak için derlenen kaynak dosyalarını (kitaplığın kendi kaynak dosyalarının yanı sıra statik geçişli bağımlılıklarla devralınan kaynak dosyaları) işleyip her kaynağa karşılık gelen .sdump dosyaları oluşturur.
    sdump oluşturma
    Şekil 1. .sdump dosyaları oluşturma
  2. header-abi-linker daha sonra, paylaşılan kitaplığa karşılık gelen tüm ABI bilgilerini günlüğe kaydeden bir .lsdump dosyası oluşturmak için .sdump dosyalarını (kendisine sağlanan bir sürüm komut dosyasını veya paylaşılan kitaplığa karşılık gelen .so dosyasını kullanarak) işler.
    lsdump oluşturma
    Şekil 2. .lsdump dosyasını oluşturma
  3. header-abi-diff, iki kitaplığın ABI'lerindeki farkları özetleyen bir fark raporu oluşturmak için .lsdump dosyasını bir referans .lsdump dosyasıyla karşılaştırır.
    abi diff creation
    Şekil 3. Fark raporu oluşturma

başlık-abi-dumper

header-abi-dumper aracı, bir C/C++ kaynak dosyasını ayrıştırır ve bu kaynak dosyadan elde edilen ABI'yi bir ara dosyaya aktarır. Derleme sistemi, tüm derlenmiş kaynak dosyalarında header-abi-dumper çalıştırırken geçişli bağımlılıklardan gelen kaynak dosyaları içeren bir kitaplık da oluşturur.

Girişler
  • C/C++ kaynak dosyası
  • Dışa aktarılan dizinleri dahil et
  • Derleyici işaretleri
Çıkış Kaynak dosyanın ABI'sini açıklayan bir dosya (örneğin, foo.sdump , foo.cpp'un ABI'sini temsil eder).

Şu anda .sdump dosyaları JSON biçimindedir. Bu biçimin gelecekteki sürümlerde de kullanılacağı garanti edilmez. Bu nedenle, .sdump dosya biçimlendirmesi bir derleme sistemi uygulama ayrıntısı olarak kabul edilmelidir.

Örneğin, libfoo.so aşağıdaki kaynak dosyaya foo.cpp sahiptir:

#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;
}

Aşağıdakileri kullanarak kaynak dosya tarafından sunulan ABI'yi temsil eden bir ara .sdump dosyası oluşturmak için header-abi-dumper kullanabilirsiniz:

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

Bu komut, header-abi-dumper'e --'yi izleyen derleyici işaretleriyle foo.cpp'ü ayrıştırmasını ve exported dizinindeki herkese açık üstbilgilerle dışa aktarılan ABI bilgilerini yayınlamasını söyler. Aşağıdaki foo.sdump, header-abi-dumper tarafından oluşturulmuştur:

{
 "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, kaynak dosya tarafından dışa aktarılan ABI bilgilerini ve herkese açık üstbilgileri (ör.

  • record_types. Herkese açık başlıklarda tanımlanan yapıları, birimleri veya sınıfları referans olarak kullanın. Her kayıt türünün alanları, boyutu, erişim tanımlayıcısı, tanımlandığı başlık dosyası ve diğer özelliklerle ilgili bilgiler vardır.
  • pointer_types. Herkese açık üstbilgilerdeki dışa aktarılan kayıtlar/işlevler tarafından doğrudan/dolaylı olarak başvurulan işaretçi türlerini ve işaretçinin gösterdiği türü (type_info içindeki referenced_type alanından) belirtir. Nitelikli türler, yerleşik C/C++ türleri, dizi türleri ve sol değer ile sağ değer referans türleri için benzer bilgiler .sdump dosyasına kaydedilir. Bu tür bilgiler, yinelenen karşılaştırma yapılmasına olanak tanır.
  • functions. Herkese açık başlıklar tarafından dışa aktarılan işlevleri temsil edin. Ayrıca işlevin bozuk adı, döndürülen tür, parametre türleri, erişim belirteci ve diğer özellikler hakkında bilgi de bulunur.

header-abi-linker

header-abi-linker aracı, header-abi-dumper tarafından oluşturulan ara dosyaları giriş olarak alır ve ardından bu dosyaları bağlar:

Girişler
  • header-abi-dumper tarafından üretilen ara dosyalar
  • Sürüm komut dosyası/harita dosyası (isteğe bağlı)
  • Paylaşılan kitaplığın .so dosyası
  • Dışa aktarılan dizinleri dahil et
Çıkış Paylaşılan bir kitaplığın ABI'sini açıklayan bir dosya (örneğin, libfoo.so.lsdump , libfoo'un ABI'sini temsil eder).

Araç, kendisine verilen tüm ara dosyalardaki tür grafiklerini birleştirir. Bu sırada, çeviri birimleri arasındaki tek tanımlı (aynı tam nitelikli ada sahip farklı çeviri birimlerindeki kullanıcı tanımlı türler anlamsal olarak farklı olabilir) farklılıkları dikkate alır. Daha sonra araç, dışa aktarılan simgelerin bir listesini oluşturmak için bir sürüm komut dosyasını veya paylaşılan kitaplığın .dynsym tablosunu (.so dosyası) ayrıştırır.

Örneğin, libfoo, foo.cpp ve bar.cpp'den oluşur. header-abi-linker, libfoo'un bağlı ABI'sinin tamamını şu şekilde oluşturmak için çağrılabilir:

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

libfoo.so.lsdump komut çıkışı örneği:

{
 "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 aracı:

  • Kendisine sağlanan .sdump dosyalarını (foo.sdump ve bar.sdump) bağlar. Bu sırada, exported dizinindeki üstbilgilerde bulunmayan ABI bilgilerini filtreler.
  • libfoo.so öğesini ayrıştırır ve kitaplık tarafından dışa aktarılan .dynsym tablosu aracılığıyla simgeler hakkında bilgi toplar.
  • _Z3FooiP3bar ve _Z6FooBadiP3foo ekler.

libfoo.so.lsdump, libfoo.so için oluşturulan son ABI dökümüdür.

header-abi-diff

header-abi-diff aracı, iki kitaplığın ABI'sini temsil eden iki .lsdump dosyasını karşılaştırır ve iki ABI arasındaki farkları belirten bir fark raporu oluşturur.

Girişler
  • Eski bir paylaşılan kitaplığın ABI'sini temsil eden .lsdump dosyası.
  • Yeni bir paylaşılan kitaplığın ABI'sini temsil eden .lsdump dosyası.
Çıkış Karşılaştırılan iki paylaşılan kitaplığın sunduğu ABI'lerdeki farklılıkları belirten bir fark raporu.

ABI fark dosyası protobuf metin biçiminde olmalıdır. Bu biçim, gelecekteki sürümlerde değiştirilebilir.

Örneğin, libfoo'nin iki sürümü vardır: libfoo_old.so ve libfoo_new.so. libfoo_new.so'te, bar_t'te mfoo türünü foo_t yerine foo_t * olarak değiştirirseniz bar_t erişilebilir bir tür olduğundan bu, header-abi-diff tarafından ABI'yi bozan bir değişiklik olarak işaretlenmelidir.

header-abi-diff'ü çalıştırmak için:

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

libfoo.so.abidiff komut çıkışı örneği:

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'daki tüm ABI'yi bozan değişikliklerin raporunu içerir. record_type_diffs mesajı, bir kaydın değiştiğini gösterir ve aşağıdakiler gibi uyumsuz değişiklikleri listeler:

  • 24 bayt olan kaydın boyutu, 8 bayt olarak değişir.
  • mfoo alanının türü foo yerine foo * olarak değişiyor (tüm typedef'ler kaldırılıyor).

type_stack alanı, header-abi-diff öğesinin değiştirilen türe (bar) nasıl eriştiğini belirtir. Bu alan, Foo öğesini parametre olarak alan, dışa aktarılan ve değiştirilen bar değerini gösteren dışa aktarılmış bir işlevdir.bar *

ABI ve API'yi zorunlu kılma

VNDK paylaşılan kitaplıklarının ABI ve API'sini zorunlu kılmak için ABI referanslarının ${ANDROID_BUILD_TOP}/prebuilts/abi-dumps/vndk/ içine kontrol edilmesi gerekir. Bu referansları oluşturmak için aşağıdaki komutu çalıştırın:

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

Referanslar oluşturulduktan sonra, kaynak kodda yapılan ve VNDK kitaplığında uyumsuz bir ABI/API değişikliğine neden olan tüm değişiklikler artık derleme hatasına neden oluyor.

Belirli kitaplıklar için ABI referanslarını güncellemek üzere aşağıdaki komutu çalıştırın:

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

Örneğin, libbinder ABI referanslarını güncellemek için şunları çalıştırın:

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