Dukungan sistem build VNDK

Di Android 8.1 dan yang lebih tinggi, sistem build memiliki dukungan VNDK bawaan. Kapan Dukungan VNDK diaktifkan, sistem build akan memeriksa dependensi antara modul, membangun varian khusus vendor untuk modul vendor, dan secara otomatis menginstal modul tersebut ke direktori yang ditentukan.

Contoh dukungan build VNDK

Dalam contoh ini, definisi modul Android.bp menentukan library bernama libexample. vendor_available menunjukkan modul framework dan modul vendor mungkin bergantung pada libexample:

libexample vendor_available:true dan vndk.enabled:true

Gambar 1. diaktifkan.

Baik framework yang dapat dieksekusi /system/bin/foo maupun vendor /vendor/bin/bar yang dapat dieksekusi bergantung pada libexample dan memiliki libexample di properti shared_libs-nya.

Jika libexample digunakan oleh modul framework dan vendor , dua varian libexample telah dibuat. Varian inti (dinamai berdasarkan libexample) digunakan oleh modul framework dan varian vendor (dinamai berdasarkan libexample.vendor) digunakan oleh vendor modul. Kedua varian diinstal ke dalam direktori yang berbeda:

  • Varian inti diinstal ke dalam /system/lib[64]/libexample.so.
  • Varian vendor diinstal ke VNDK APEX karena vndk.enabled adalah true.

Untuk detail selengkapnya, lihat Definisi modul.

Mengonfigurasi dukungan build

Untuk mengaktifkan dukungan sistem build penuh untuk perangkat produk, tambahkan BOARD_VNDK_VERSION ke BoardConfig.mk:

BOARD_VNDK_VERSION := current

Setelan ini memiliki efek global: Jika ditentukan di BoardConfig.mk, semua modul telah diperiksa. Karena tidak ada mekanisme untuk memasukkan modul yang bermasalah ke daftar yang tidak diizinkan atau daftar yang diizinkan, Anda harus dependensi yang tidak diperlukan sebelum menambahkan BOARD_VNDK_VERSION. Anda dapat menguji dan mengompilasi modul dengan menyetel BOARD_VNDK_VERSION di variabel lingkungan Anda:

$ BOARD_VNDK_VERSION=current m module_name.vendor

Jika BOARD_VNDK_VERSION diaktifkan, beberapa file global default jalur penelusuran header akan dihapus. Ini mencakup:

  • frameworks/av/include
  • frameworks/native/include
  • frameworks/native/opengl/include
  • hardware/libhardware/include
  • hardware/libhardware_legacy/include
  • hardware/ril/include
  • libnativehelper/include
  • libnativehelper/include_deprecated
  • system/core/include
  • system/media/audio/include

Jika modul bergantung pada header dari direktori ini, Anda harus menentukan (secara eksplisit) dependensi dengan header_libs, static_libs, dan/atau shared_libs.

APEX VNDK

Di Android 10 dan yang lebih rendah, modul dengan vndk.enabled telah diinstal di /system/lib[64]/vndk[-sp]-${VER}. Di Android 11 dan yang lebih tinggi, Library VNDK dikemas dalam format APEX dan nama VNDK APEX adalah com.android.vndk.v${VER}. Tergantung dari konfigurasi perangkat, APEX VNDK diratakan atau tidak diratakan dan tersedia dari jalur kanonis /apex/com.android.vndk.v${VER}.

APEX VNDK

Gambar 2. APEX VNDK.

Definisi modul

Untuk membangun Android dengan BOARD_VNDK_VERSION, Anda harus merevisi definisi modul dalam Android.mk atau Android.bp. Bagian ini menjelaskan berbagai jenis modul definisi, beberapa properti modul terkait VNDK, dan pemeriksaan dependensi yang diimplementasikan dalam sistem build.

Modul vendor

Modul vendor adalah {i>executable<i} khusus vendor atau {i>shared library<i} yang harus diinstal ke dalam partisi vendor. Dalam Android.bp file, modul vendor harus menetapkan properti eksklusif atau vendor ke true. Dalam file Android.mk, modul vendor harus ditetapkan LOCAL_VENDOR_MODULE atau LOCAL_PROPRIETARY_MODULE ke true.

Jika BOARD_VNDK_VERSION ditentukan, sistem build tidak akan mengizinkan dependensi antara modul vendor dan modul framework serta menimbulkan error jika:

  • modul tanpa vendor:true bergantung pada modul dengan vendor:true, atau
  • modul dengan vendor:true bergantung pada modul non-llndk_library yang tidak memiliki vendor:true atau vendor_available:true.

Pemeriksaan dependensi berlaku untuk header_libs, static_libs, dan shared_libs inci Android.bp, dan ke LOCAL_HEADER_LIBRARIES, LOCAL_STATIC_LIBRARIES dan LOCAL_SHARED_LIBRARIES di Android.mk.

LL-NDK

Library bersama LL-NDK adalah library bersama dengan ABI yang stabil. Kedua framework dan modul vendor berbagi implementasi yang sama dan terbaru. Untuk setiap Library bersama LL-NDK, cc_library berisi Properti llndk dengan file simbol:

cc_library {
    name: "libvndksupport",
    llndk: {
        symbol_file: "libvndksupport.map.txt",
    },
}

File simbol menjelaskan simbol yang terlihat oleh modul vendor. Contoh:

LIBVNDKSUPPORT {
  global:
    android_load_sphal_library; # llndk
    android_unload_sphal_library; # llndk
  local:
    *;
};

Berdasarkan file simbolnya, sistem build akan menghasilkan library bersama stub untuk modul vendor, yang terhubung dengan library ini saat BOARD_VNDK_VERSION diaktifkan. Simbol disertakan dalam stub pustaka bersama hanya jika:

  • Tidak ditentukan di bagian yang diakhiri dengan _PRIVATE atau _PLATFORM,
  • Tidak memiliki tag #platform-only, dan
  • Tidak memiliki tag #introduce* atau tag yang cocok dengan target.

VNDK

Dalam Android.bp file, cc_library, cc_library_static, cc_library_shared, dan Definisi modul cc_library_headers mendukung tiga terkait VNDK properti: vendor_available, vndk.enabled, dan vndk.support_system_process.

Jika vendor_available atau vndk.enabled adalah true, dua varian (inti dan vendor) mungkin dibuat. Varian inti harus diperlakukan sebagai modul framework dan vendor harus diperlakukan sebagai modul vendor. Jika beberapa modul framework bergantung di modul ini, varian inti akan dibuat. Jika beberapa modul vendor bergantung pada modul ini, varian vendor akan dibangun. Sistem build menerapkan pemeriksaan dependensi berikut:

  • Varian inti selalu bersifat khusus framework dan tidak dapat diakses oleh vendor modul.
  • Varian vendor selalu tidak dapat diakses oleh modul framework.
  • Semua dependensi varian vendor, yang ditentukan dalam header_libs, static_libs, dan/atau shared_libs, harus berupa llndk_library atau dengan vendor_available atau vndk.enabled.
  • Jika vendor_available adalah true, varian vendor dapat diakses oleh semua modul vendor.
  • Jika vendor_available adalah false, varian vendor hanya dapat diakses oleh modul VNDK atau VNDK-SP lainnya (yaitu, modul dengan vendor:true tidak dapat menautkan vendor_available:false ).

Jalur penginstalan default untuk cc_library atau cc_library_shared ditentukan oleh aturan berikut:

  • Varian inti diinstal ke /system/lib[64].
  • Jalur penginstalan varian vendor dapat bervariasi:
    • Jika vndk.enabled adalah false, varian vendor diinstal ke /vendor/lib[64].
    • Jika vndk.enabled adalah true, varian vendor diinstal ke VNDK APEX(com.android.vndk.v${VER}).

Tabel di bawah ini merangkum cara sistem build menangani varian vendor:

vendor_available vndk
diaktifkan
vndk
support_same_process
Deskripsi varian vendor
true false false Varian vendor bersifat KHUSUS VND. {i>Shared library<i} adalah diinstal ke /vendor/lib[64].
true Tidak valid (Error build)
true false Varian vendor adalah VNDK. Galeri foto bersama telah diinstal ke VNDK APEX.
true Varian vendor adalah VNDK-SP. {i>Shared library<i} adalah yang diinstal ke VNDK APEX.

false

false

false

Tidak ada varian vendor. Modul ini KHUSUS FWK.

true Tidak valid (Error build)
true false Varian vendor adalah VNDK-Private. {i>Shared library<i} adalah yang diinstal ke VNDK APEX. Tidak boleh berupa langsung digunakan oleh modul vendor.
true Varian vendor adalah VNDK-SP-Private. {i>Shared library<i} adalah yang diinstal ke VNDK APEX. Tidak boleh berupa langsung digunakan oleh modul vendor.

Ekstensi VNDK

Ekstensi VNDK adalah library bersama VNDK dengan API tambahan. Ekstensi adalah diinstal ke /vendor/lib[64]/vndk[-sp] (tanpa akhiran versi) dan mengganti library bersama VNDK asli saat runtime.

Menentukan ekstensi VNDK

Di Android 9 dan yang lebih tinggi, Android.bp secara native mendukung VNDK ekstensi. Untuk membangun ekstensi VNDK, tentukan modul lain dengan vendor:true dan properti extends:

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

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
}

Modul dengan vendor:true, vndk.enabled:true, dan Properti extends menentukan ekstensi VNDK:

  • Properti extends harus menentukan library bersama VNDK dasar (atau nama library bersama VNDK-SP).
  • Ekstensi VNDK (atau ekstensi VNDK-SP) diberi nama berdasarkan modul dasar nama-nama dari mana mereka memperluas. Misalnya, biner output dari libvndk_ext adalah libvndk.so, bukan libvndk_ext.so.
  • Ekstensi VNDK diinstal ke /vendor/lib[64]/vndk.
  • Ekstensi VNDK-SP diinstal ke dalam /vendor/lib[64]/vndk-sp.
  • Library bersama dasar harus memiliki vndk.enabled:true dan vendor_available:true.

Ekstensi VNDK-SP harus diperluas dari library bersama VNDK-SP (vndk.support_system_process harus sama):

cc_library {
    name: "libvndk_sp",
    vendor_available: true,
    vndk: {
        enabled: true,
        support_system_process: true,
    },
}

cc_library {
    name: "libvndk_sp_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk_sp",
        support_system_process: true,
    },
}

Ekstensi VNDK (atau ekstensi VNDK-SP) mungkin bergantung pada ekstensi bersama vendor lainnya {i>library<i}:

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

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
    shared_libs: [
        "libvendor",
    ],
}

cc_library {
    name: "libvendor",
    vendor: true,
}

Menggunakan ekstensi VNDK

Jika modul vendor bergantung pada API tambahan yang ditetapkan oleh ekstensi VNDK, harus mencantumkan nama ekstensi VNDK dalam shared_libs properti:

// A vendor shared library example
cc_library {
    name: "libvendor",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

// A vendor executable example
cc_binary {
    name: "vendor-example",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

Jika modul vendor bergantung pada ekstensi VNDK, ekstensi VNDK tersebut akan diinstal ke /vendor/lib[64]/vndk[-sp] secara otomatis. Jika modul tidak lagi bergantung pada ekstensi VNDK, tambahkan langkah bersih ke CleanSpec.mk untuk menghapus galeri foto bersama. Contoh:

$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)

Kompilasi bersyarat

Bagian ini menjelaskan cara menangani perbedaan kecil (mis. menambahkan atau menghapus fitur dari salah satu varian) di antara yang berikut tiga library bersama VNDK:

  • Varian inti (misalnya, /system/lib[64]/libexample.so)
  • Varian vendor (mis. /apex/com.android.vndk.v${VER}/lib[64]/libexample.so)
  • Ekstensi VNDK (misalnya, /vendor/lib[64]/vndk[-sp]/libexample.so)

Tanda compiler bersyarat

Sistem build Android menentukan __ANDROID_VNDK__ untuk vendor dan ekstensi VNDK secara default. Anda dapat menjaga kode dengan pelindung preprocessor C:

void all() { }

#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif

#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif

Selain __ANDROID_VNDK__, cflags atau cppflags dapat ditentukan di Android.bp. Tujuan cflags atau cppflags ditentukan di target.vendor bersifat khusus untuk varian vendor.

Misalnya, Android.bp berikut menentukan libexample dan libexample_ext:

cc_library {
    name: "libexample",
    srcs: ["src/example.c"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
    target: {
        vendor: {
            cflags: ["-DLIBEXAMPLE_ENABLE_VNDK=1"],
        },
    },
}

cc_library {
    name: "libexample_ext",
    srcs: ["src/example.c"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
    cflags: [
        "-DLIBEXAMPLE_ENABLE_VNDK=1",
        "-DLIBEXAMPLE_ENABLE_VNDK_EXT=1",
    ],
}

Dan ini adalah listingan kode src/example.c:

void all() { }

#if !defined(LIBEXAMPLE_ENABLE_VNDK)
void framework_only() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK)
void vndk() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK_EXT)
void vndk_ext() { }
#endif

Menurut kedua file ini, sistem build menghasilkan library bersama dengan simbol yang diekspor berikut:

Jalur penginstalan Simbol yang diekspor
/system/lib[64]/libexample.so all, framework_only
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so all, vndk
/vendor/lib[64]/vndk/libexample.so all, vndk, vndk_ext

Persyaratan terkait simbol yang diekspor

Pemeriksa ABI VNDK membandingkan ABI varian vendor VNDK dan Ekstensi VNDK ke dump ABI referensi di bagian prebuilts/abi-dumps/vndk.

  • Simbol yang diekspor oleh varian vendor VNDK (mis. /apex/com.android.vndk.v${VER}/lib[64]/libexample.so) harus sama ke (bukan superset dari) simbol yang ditentukan dalam dump ABI.
  • Simbol yang diekspor oleh ekstensi VNDK (mis. /vendor/lib[64]/vndk/libexample.so) harus berupa superset dari simbol yang ditentukan dalam dump ABI.

Jika Varian vendor VNDK atau ekstensi VNDK gagal diikuti persyaratan di atas, pemeriksa ABI VNDK akan memunculkan error build dan menghentikan buat.

Mengecualikan file sumber atau library bersama dari varian vendor

Untuk mengecualikan file sumber dari varian vendor, tambahkan file tersebut ke exclude_srcs. Demikian pula, untuk memastikan pustaka bersama tidak ditautkan dengan varian vendor, tambahkan library tersebut ke exclude_shared_libs. Contoh:

cc_library {
    name: "libexample_cond_exclude",
    srcs: ["fwk.c", "both.c"],
    shared_libs: ["libfwk_only", "libboth"],
    vendor_available: true,
    target: {
        vendor: {
            exclude_srcs: ["fwk.c"],
            exclude_shared_libs: ["libfwk_only"],
        },
    },
}

Dalam contoh ini, varian inti libexample_cond_exclude menyertakan kode dari fwk.c dan both.c serta bergantung di library bersama libfwk_only dan libboth. Tujuan varian vendor libexample_cond_exclude hanya menyertakan kode dari both.c karena fwk.c dikecualikan oleh properti exclude_srcs. Demikian pula, hal ini hanya bergantung pada library bersama. libboth karena libfwk_only dikecualikan oleh exclude_shared_libs.

Mengekspor header dari ekstensi VNDK

Ekstensi VNDK dapat menambahkan class baru atau fungsi baru ke file VNDK bersama library. Sebaiknya simpan deklarasi tersebut di header independen dan hindari mengubah {i>header<i} yang ada.

Misalnya, file header baru include-ext/example/ext/feature_name.h dibuat untuk VNDK ekstensi libexample_ext:

  • Android.bp
  • include-ext/example/ext/feature_name.h
  • sertakan/contoh/contoh.h
  • src/example.c
  • src/ext/feature_name.c

Dalam Android.bp berikut, libexample ekspor hanya include, sedangkan libexample_ext mengekspor keduanya include dan include-ext. Hal ini memastikan feature_name.h tidak akan salah disertakan oleh pengguna libexample:

cc_library {
    name: "libexample",
    srcs: ["src/example.c"],
    export_include_dirs: ["include"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libexample_ext",
    srcs: [
        "src/example.c",
        "src/ext/feature_name.c",
    ],
    export_include_dirs: [
        "include",
        "include-ext",
    ],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
}

Jika memisahkan ekstensi ke file {i>header<i} independen tidak dapat dilakukan, alternatifnya adalah dengan menambahkan guard #ifdef. Namun, pastikan bahwa Pengguna ekstensi VNDK menambahkan flag tentukan. Anda dapat menentukan cc_defaults untuk menambahkan tanda ke cflags dan menautkan library bersama dengan shared_libs.

Misalnya, untuk menambahkan fungsi anggota baru Example2::get_b() ke ekstensi VNDK libexample2_ext, Anda harus mengubah elemen dan menambahkan guard #ifdef:

#ifndef LIBEXAMPLE2_EXAMPLE_H_
#define LIBEXAMPLE2_EXAMPLE_H_

class Example2 {
 public:
  Example2();

  void get_a();

#ifdef LIBEXAMPLE2_ENABLE_VNDK_EXT
  void get_b();
#endif

 private:
  void *impl_;
};

#endif  // LIBEXAMPLE2_EXAMPLE_H_

cc_defaults bernama libexample2_ext_defaults adalah yang ditentukan untuk pengguna libexample2_ext:

cc_library {
    name: "libexample2",
    srcs: ["src/example2.cpp"],
    export_include_dirs: ["include"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libexample2_ext",
    srcs: ["src/example2.cpp"],
    export_include_dirs: ["include"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample2",
    },
    cflags: [
        "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1",
    ],
}

cc_defaults {
    name: "libexample2_ext_defaults",
    shared_libs: [
        "libexample2_ext",
    ],
    cflags: [
        "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1",
    ],
}

Pengguna libexample2_ext mungkin hanya menyertakan libexample2_ext_defaults di defaults mereka properti:

cc_binary {
    name: "example2_user_executable",
    defaults: ["libexample2_ext_defaults"],
    vendor: true,
}

Paket produk

Dalam sistem build Android, variabel PRODUCT_PACKAGES menentukan {i>executable<i}, {i> shared library<i}, atau paket yang harus diinstal ke dalam perangkat. Dependensi transitif dari secara implisit juga diinstal ke dalam perangkat.

Jika BOARD_VNDK_VERSION diaktifkan, modul dengan Dapatkan spesial vendor_available atau vndk.enabled perlakuan. Jika modul framework bergantung pada modul dengan vendor_available atau vndk.enabled, varian inti disertakan dalam set penginstalan transitif. Jika modul vendor bergantung pada modul dengan vendor_available, varian vendornya disertakan dalam set instalasi transitif. Namun, varian vendor dari modul dengan vndk.enabled akan diinstal baik saat digunakan oleh modul vendor maupun tidak.

Saat dependensi tidak terlihat oleh sistem build (mis. library bersama yang dapat dibuka dengan dlopen() dalam runtime), Anda harus menentukan nama modul di PRODUCT_PACKAGES untuk menginstal modul tersebut secara eksplisit.

Jika modul memiliki vendor_available atau vndk.enabled, nama modul adalah singkatan dari varian intinya. Untuk menentukan secara eksplisit varian vendor di PRODUCT_PACKAGES, tambahkan .vendor akhiran pada nama modul. Contoh:

cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
}

Dalam contoh ini, libexample adalah singkatan dari /system/lib[64]/libexample.so dan libexample.vendor adalah singkatan dari /vendor/lib[64]/libexample.so. Untuk menginstal /vendor/lib[64]/libexample.so, tambahkan libexample.vendor ke PRODUCT_PACKAGES:

PRODUCT_PACKAGES += libexample.vendor