Hỗ trợ hệ thống xây dựng VNDK

Trên Android 8.1 trở lên, hệ thống xây dựng đã tích hợp sẵn tính năng hỗ trợ VNDK. Thời gian Đã bật tính năng hỗ trợ VNDK, hệ thống xây dựng sẽ kiểm tra các phần phụ thuộc giữa mô-đun, tạo biến thể dành riêng cho nhà cung cấp cho các mô-đun nhà cung cấp và tự động cài đặt các mô-đun đó vào thư mục được chỉ định.

Ví dụ về tính năng hỗ trợ bản dựng VNDK

Trong ví dụ này, định nghĩa mô-đun Android.bp sẽ xác định một thư viện có tên libexample. vendor_available thuộc tính cho biết mô-đun khung và mô-đun nhà cung cấp có thể phụ thuộc vào libexample:

libexamplevendor_available:true và vndk.enabled:true

Hình 1. Đã bật chế độ hỗ trợ.

Cả /system/bin/foo có thể thực thi của khung và nhà cung cấp /vendor/bin/bar có thể thực thi phụ thuộc vào libexample và có libexample trong thuộc tính shared_libs của chúng.

Nếu libexample được cả mô-đun khung và nhà cung cấp sử dụng mô-đun, có hai biến thể của libexample được xây dựng. Biến thể chính (được đặt tên sau libexample) được sử dụng bởi các mô-đun khung và biến thể của nhà cung cấp (được đặt tên sau libexample.vendor) được nhà cung cấp sử dụng các mô-đun. Hai biến thể này được cài đặt trong các thư mục khác nhau:

  • Biến thể chính được cài đặt vào /system/lib[64]/libexample.so.
  • Biến thể nhà cung cấp được cài đặt vào VNDK APEX vì vndk.enabledtrue.

Để biết thêm thông tin chi tiết, hãy xem phần Định nghĩa mô-đun.

Định cấu hình tính năng hỗ trợ bản dựng

Để bật tính năng hỗ trợ đầy đủ cho hệ thống xây dựng cho một thiết bị của sản phẩm, hãy thêm BOARD_VNDK_VERSION thành BoardConfig.mk:

BOARD_VNDK_VERSION := current

Chế độ cài đặt này có hiệu ứng chung: Khi được xác định trong BoardConfig.mk thân mến! Đã kiểm tra tất cả các mô-đun. Do không có cơ chế vào danh sách cấm hoặc đưa mô-đun vi phạm vào danh sách cho phép, bạn nên xoá tất cả các phần phụ thuộc không cần thiết trước khi thêm BOARD_VNDK_VERSION. Bạn có thể kiểm thử và biên dịch một mô-đun bằng cách đặt BOARD_VNDK_VERSION trong biến môi trường của bạn:

$ BOARD_VNDK_VERSION=current m module_name.vendor

Khi BOARD_VNDK_VERSION được bật, một số quyền truy cập chung mặc định đường dẫn tìm kiếm ở tiêu đề đã bị xoá. Những quốc gia/khu vực này bao gồm:

  • 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

Nếu một mô-đun phụ thuộc vào tiêu đề từ các thư mục này, bạn phải chỉ định (rõ ràng) các phần phụ thuộc với header_libs, static_libs và/hoặc shared_libs.

VẬN CHUYỂN VNĐ

Trong Android 10 trở xuống, các mô-đun có vndk.enabled được cài đặt trong /system/lib[64]/vndk[-sp]-${VER}. Trong Android 11 trở lên, Các thư viện của VNDK được đóng gói theo định dạng APEX và tên của VNDK APEX là com.android.vndk.v${VER}. Tuỳ thuộc vào cấu hình thiết bị, VNDK APEX có dạng đã làm phẳng hoặc không làm phẳng và có trong đường dẫn chính tắc /apex/com.android.vndk.v${VER}.

VẬN CHUYỂN VNĐ

Hình 2. PHỤ LỤC VNDK.

Định nghĩa mô-đun

Để xây dựng Android bằng BOARD_VNDK_VERSION, bạn phải sửa đổi định nghĩa mô-đun trong Android.mk hoặc Android.bp. Phần này mô tả các loại mô-đun khác nhau định nghĩa, một vài thuộc tính mô-đun liên quan đến VNDK và kiểm tra phần phụ thuộc triển khai trong hệ thống xây dựng.

Mô-đun nhà cung cấp

Mô-đun nhà cung cấp là các tệp thực thi dành riêng cho nhà cung cấp hoặc thư viện dùng chung phải được cài đặt vào phân vùng nhà cung cấp. Trong tệp Android.bp, mô-đun của nhà cung cấp phải đặt tài sản của nhà cung cấp hoặc tài sản thuộc quyền sở hữu riêng thành true. Trong các tệp Android.mk, mô-đun nhà cung cấp phải đặt LOCAL_VENDOR_MODULE hoặc LOCAL_PROPRIETARY_MODULE đến true.

Nếu BOARD_VNDK_VERSION được định nghĩa, hệ thống xây dựng không cho phép phần phụ thuộc giữa mô-đun nhà cung cấp và mô-đun khung, đồng thời phát ra lỗi nếu:

  • một mô-đun không có vendor:true phụ thuộc vào một mô-đun có vendor:true hoặc
  • một mô-đun có vendor:true phụ thuộc vào một không phải là mô-đun llndk_library không có vendor:true hoặc vendor_available:true.

Bước kiểm tra phần phụ thuộc áp dụng cho header_libs, static_libsshared_libs inch Android.bp và với LOCAL_HEADER_LIBRARIES, LOCAL_STATIC_LIBRARIESLOCAL_SHARED_LIBRARIES inch Android.mk.

LL-NDK

Thư viện dùng chung LL-NDK là thư viện dùng chung có các ABI ổn định. Cả hai khung và mô-đun nhà cung cấp có cùng cách triển khai và cách triển khai mới nhất. Đối với mỗi Thư viện dùng chung LL-NDK, cc_library chứa một Thuộc tính llndk có tệp biểu tượng:

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

Tệp biểu tượng mô tả các ký hiệu hiển thị cho mô-đun của nhà cung cấp. Ví dụ:

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

Dựa trên tệp biểu tượng, hệ thống xây dựng tạo một thư viện dùng chung mã giả lập cho các mô-đun của nhà cung cấp, liên kết với các thư viện này khi Đã bật BOARD_VNDK_VERSION. Một biểu tượng được bao gồm trong mã giả lập thư viện được chia sẻ chỉ khi thư viện đó:

  • Không được xác định trong phần kết thúc bằng _PRIVATE hoặc _PLATFORM,
  • Không có thẻ #platform-only
  • Không có thẻ #introduce* hoặc thẻ này khớp với .

VNDK

Trong tệp Android.bp, cc_library, cc_library_static, cc_library_shared và Định nghĩa mô-đun cc_library_headers hỗ trợ ba định nghĩa liên quan đến VNDK thuộc tính: vendor_available, vndk.enabledvndk.support_system_process.

Nếu vendor_available hoặc vndk.enabledtrue, 2 biến thể (corevendor) có thể là tạo. Biến thể chính nên được coi là một mô-đun khung và nhà cung cấp biến thể sẽ được coi là mô-đun nhà cung cấp. Nếu một số mô-đun khung phụ thuộc trên mô-đun này, biến thể cốt lõi sẽ được xây dựng. Nếu một số mô-đun của nhà cung cấp phụ thuộc vào mô-đun này, biến thể nhà cung cấp sẽ được tạo. Hệ thống xây dựng thực thi các bước kiểm tra phần phụ thuộc sau đây:

  • Biến thể chính luôn chỉ ở dạng khung và nhà cung cấp không thể truy cập được các mô-đun.
  • Các mô-đun khung luôn không thể truy cập vào biến thể nhà cung cấp.
  • Tất cả phần phụ thuộc của biến thể nhà cung cấp, được chỉ định trong header_libs, static_libs và/hoặc shared_libs, phải là llndk_library hoặc với vendor_available hoặc vndk.enabled.
  • Nếu vendor_availabletrue, biến thể của nhà cung cấp có thể truy cập vào tất cả mô-đun của nhà cung cấp.
  • Nếu vendor_availablefalse, biến thể của nhà cung cấp chỉ truy cập được vào các mô-đun VNDK hoặc VNDK-SP khác (ví dụ: các mô-đun có vendor:true không thể liên kết vendor_available:false mô-đun).

Đường dẫn cài đặt mặc định cho cc_library hoặc cc_library_shared được xác định theo các quy tắc sau:

  • Biến thể chính được cài đặt vào /system/lib[64].
  • Đường dẫn cài đặt biến thể nhà cung cấp có thể khác nhau:
    • Nếu vndk.enabledfalse, biến thể của nhà cung cấp được cài đặt vào /vendor/lib[64].
    • Nếu vndk.enabledtrue, biến thể của nhà cung cấp được cài đặt vào VNDK APEX(com.android.vndk.v${VER}).

Bảng dưới đây tóm tắt cách hệ thống xây dựng xử lý các biến thể của nhà cung cấp:

nhà cung cấp có sẵn đã bật vndk
vndk
support_same_process
Mô tả biến thể nhà cung cấp
true false false Các biến thể của nhà cung cấp là CHỈ VND. Thư viện chia sẻ được cài đặt vào /vendor/lib[64].
true Không hợp lệ (Lỗi bản dựng)
true false Các biến thể của nhà cung cấp là VNDK. Đã cài đặt thư viện chia sẻ sang VNDK APEX.
true Các biến thể của nhà cung cấp là VNDK-SP. Thư viện chia sẻ được cài đặt vào VNDK APEX.

false

false

false

Không có biến thể của nhà cung cấp. Mô-đun này CHỈ DÀNH CHO FWK.

true Không hợp lệ (Lỗi bản dựng)
true false Các biến thể của nhà cung cấp là VNDK-Private. Thư viện chia sẻ được cài đặt vào VNDK APEX. Những thông tin này không được được các mô-đun nhà cung cấp trực tiếp sử dụng.
true Các biến thể của nhà cung cấp là VNDK-SP-Private. Thư viện chia sẻ được cài đặt vào VNDK APEX. Những thông tin này không được được các mô-đun nhà cung cấp trực tiếp sử dụng.

Phần mở rộng VNDK

Phần mở rộng của VNDK là các thư viện dùng chung của VNDK có các API bổ sung. Các tiện ích là được cài đặt vào /vendor/lib[64]/vndk[-sp] (không có hậu tố phiên bản) và ghi đè thư viện chia sẻ VNDK gốc trong thời gian chạy.

Xác định phần mở rộng VNDK

Trên Android 9 trở lên, Android.bp vốn hỗ trợ VNDK tiện ích. Để tạo một tiện ích VNDK, hãy xác định một mô-đun khác có vendor:true và một thuộc tính extends:

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

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

Một mô-đun có vendor:true, vndk.enabled:true và Các thuộc tính extends xác định phần mở rộng VNDK:

  • Thuộc tính extends phải chỉ định một thư viện chia sẻ VNDK cơ sở tên (hoặc tên thư viện chia sẻ VNDK-SP).
  • Các phần mở rộng VNDK (hay phần mở rộng VNDK-SP) được đặt tên theo mô-đun cơ sở tên mà chúng mở rộng. Ví dụ: tệp nhị phân đầu ra của libvndk_extlibvndk.so thay vì libvndk_ext.so.
  • Các tiện ích VNDK được cài đặt vào /vendor/lib[64]/vndk.
  • Tiện ích VNDK-SP được cài đặt vào /vendor/lib[64]/vndk-sp.
  • Thư viện dùng chung cơ sở phải có cả vndk.enabled:truevendor_available:true.

Tiện ích VNDK-SP phải mở rộng từ thư viện chia sẻ VNDK-SP (vndk.support_system_process phải bằng):

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,
    },
}

Các phần mở rộng VNDK (hoặc các phần mở rộng VNDK-SP) có thể phụ thuộc vào các nhà cung cấp khác dùng chung thư viện:

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,
}

Sử dụng tiện ích VNDK

Nếu một mô-đun nhà cung cấp phụ thuộc vào các API bổ sung do các tiện ích VNDK xác định, mô-đun phải chỉ định tên tiện ích VNDK trong Thuộc tính shared_libs:

// 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",
    ],
}

Nếu một mô-đun nhà cung cấp phụ thuộc vào các tiện ích VNDK, thì các tiện ích VNDK đó được tự động cài đặt vào /vendor/lib[64]/vndk[-sp]. Nếu một mô-đun không còn phụ thuộc vào tiện ích VNDK nữa, hãy thêm một bước rõ ràng vào CleanSpec.mk để xoá thư viện chia sẻ. Ví dụ:

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

Biên dịch có điều kiện

Phần này mô tả cách giải quyết những khác biệt nhỏ (ví dụ: thêm hoặc loại bỏ tính năng khỏi một trong các biến thể) giữa các biến thể sau 3 thư viện dùng chung VNDK:

  • Biến thể chính (ví dụ: /system/lib[64]/libexample.so)
  • Biến thể nhà cung cấp (ví dụ: /apex/com.android.vndk.v${VER}/lib[64]/libexample.so)
  • Phần mở rộng VNDK (ví dụ: /vendor/lib[64]/vndk[-sp]/libexample.so)

Cờ trình biên dịch có điều kiện

Hệ thống xây dựng Android định nghĩa __ANDROID_VNDK__ cho nhà cung cấp và phần mở rộng VNDK theo mặc định. Bạn có thể bảo vệ mã với các biện pháp bảo vệ bộ tiền xử lý C:

void all() { }

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

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

Ngoài __ANDROID_VNDK__, các cflags hoặc Bạn có thể chỉ định cppflags trong Android.bp. Chiến lược phát hành đĩa đơn cflags hoặc cppflags được chỉ định trong target.vendor dành riêng cho biến thể nhà cung cấp.

Ví dụ: Android.bp sau đây xác định libexamplelibexample_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",
    ],
}

Và đây là danh sách mã của 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

Theo 2 tệp này, hệ thống xây dựng tạo ra thư viện dùng chung với các ký hiệu được xuất sau:

Đường dẫn cài đặt Biểu tượng đã xuất
/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

Yêu cầu đối với biểu tượng được xuất

Trình kiểm tra ABI VNDK so sánh ABI của các biến thể của nhà cung cấp VNDKCác tiện ích VNDK cho tệp kết xuất ABI tham chiếu trong prebuilts/abi-dumps/vndk.

  • Biểu tượng được xuất qua các biến thể của nhà cung cấp VNDK (ví dụ: /apex/com.android.vndk.v${VER}/lib[64]/libexample.so) phải giống hệt nhau đến (không phải là tập mẹ của) các ký hiệu được xác định trong tệp kết xuất ABI.
  • Biểu tượng được xuất bằng tiện ích VNDK (ví dụ: /vendor/lib[64]/vndk/libexample.so) phải là tập mẹ của ký hiệu được xác định trong tệp kết xuất ABI.

Nếu các biến thể của nhà cung cấp VNDK hoặc tiện ích VNDK không tuân theo theo yêu cầu nêu trên, trình kiểm tra ABIK ABI phát ra lỗi bản dựng và ngừng bản dựng.

Loại trừ tệp nguồn hoặc thư viện chia sẻ khỏi các biến thể của nhà cung cấp

Để loại trừ tệp nguồn khỏi biến thể nhà cung cấp, hãy thêm các tệp đó vào Thuộc tính exclude_srcs. Tương tự như vậy, để đảm bảo thư viện dùng chung không được liên kết với biến thể của nhà cung cấp, hãy thêm các thư viện đó vào Thuộc tính exclude_shared_libs. Ví dụ:

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"],
        },
    },
}

Trong ví dụ này, biến thể chính của libexample_cond_exclude bao gồm mã từ fwk.cboth.c và phụ thuộc trên thư viện dùng chung libfwk_onlylibboth. Chiến lược phát hành đĩa đơn biến thể nhà cung cấp của libexample_cond_exclude chỉ bao gồm mã khỏi both.cfwk.c bị loại trừ bởi thuộc tính exclude_srcs. Tương tự, việc này chỉ phụ thuộc vào thư viện chia sẻ libbothlibfwk_only bị loại trừ bởi thuộc tính exclude_shared_libs.

Xuất tiêu đề từ tiện ích VNDK

Tiện ích VNDK có thể thêm lớp mới hoặc chức năng mới vào một tiện ích VNDK được chia sẻ thư viện của bạn. Bạn nên giữ lại các nội dung khai báo đó trong các tiêu đề độc lập và tránh thay đổi tiêu đề hiện tại.

Ví dụ: tệp tiêu đề mới include-ext/example/ext/feature_name.h được tạo cho VNDK phần mở rộng libexample_ext:

  • Android.bp
  • include-ext/example/ext/feature_name.h
  • bao gồm/example/example.h
  • src/example.c
  • src/ext/feature_name.c

Trong Android.bp sau đây, libexample tệp xuất chỉ include, trong khi libexample_ext xuất cả hai includeinclude-ext. Điều này giúp đảm bảo feature_name.h sẽ không được đưa vào nhầm bởi người dùng của 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",
    },
}

Nếu không thể tách các tiện ích mở rộng thành các tệp tiêu đề độc lập, một cách khác là thêm #ifdef bảo vệ. Tuy nhiên, hãy đảm bảo rằng tất cả Người dùng tiện ích VNDK sẽ thêm cờ xác định. Bạn có thể xác định cc_defaults để thêm cờ định nghĩa vào cflags và liên kết thư viện dùng chung với shared_libs.

Ví dụ: để thêm một hàm thành phần mới Example2::get_b() vào tiện ích VNDK libexample2_ext, bạn phải sửa đổi tệp tiêu đề và thêm lớp bảo vệ #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 có tên là libexample2_ext_defaults được xác định cho người dùng 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",
    ],
}

Người dùng libexample2_ext có thể chỉ cần bao gồm libexample2_ext_defaults trong defaults của họ thuộc tính:

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

Gói sản phẩm

Trong hệ thống xây dựng Android, biến PRODUCT_PACKAGES chỉ định tệp thực thi, thư viện dùng chung hoặc gói cần được được cài đặt vào thiết bị. Các phần phụ thuộc bắc cầu của thuộc tính được chỉ định các mô-đun cũng được cài đặt ngầm vào thiết bị.

Nếu BOARD_VNDK_VERSION được bật, các mô-đun có vendor_available hoặc vndk.enabled nhận ưu đãi đặc biệt xử lý. Nếu một mô-đun khung phụ thuộc vào một mô-đun có vendor_available hoặc vndk.enabled, biến thể chính được bao gồm trong nhóm cài đặt bắc cầu. Nếu mô-đun nhà cung cấp phụ thuộc vào một mô-đun có vendor_available, biến thể nhà cung cấp là có trong nhóm cài đặt bắc cầu. Tuy nhiên, các biến thể của nhà cung cấp của mô-đun với vndk.enabled đã được cài đặt cho dù các mô-đun của nhà cung cấp có sử dụng chúng hay không.

Khi hệ thống xây dựng không nhìn thấy các phần phụ thuộc (ví dụ: thư viện dùng chung có thể mở bằng dlopen() trong thời gian chạy), bạn nên chỉ định tên mô-đun trong PRODUCT_PACKAGES để cài đặt các mô-đun đó một cách rõ ràng.

Nếu một mô-đun có vendor_available hoặc vndk.enabled, tên mô-đun là viết tắt của biến thể chính. Để chỉ định rõ ràng biến thể nhà cung cấp trong PRODUCT_PACKAGES, hãy thêm .vendor hậu tố vào tên mô-đun. Ví dụ:

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

Trong ví dụ này, libexample là viết tắt của cụm từ /system/lib[64]/libexample.solibexample.vendor là viết tắt của /vendor/lib[64]/libexample.so. Cách cài đặt /vendor/lib[64]/libexample.so, thêm libexample.vendor đến PRODUCT_PACKAGES:

PRODUCT_PACKAGES += libexample.vendor