Công cụ định nghĩa VNDK

Công cụ định nghĩa VNDK giúp các nhà cung cấp di chuyển cây nguồn của họ sang môi trường Android 8.0. Công cụ này quét các tệp nhị phân trong hệ thống và hình ảnh nhà cung cấp, sau đó giải quyết các phần phụ thuộc. Dựa trên biểu đồ phụ thuộc mô-đun, công cụ cũng có thể phát hiện các vi phạm đối với khái niệm VNDK và cung cấp thông tin chi tiết/đề xuất để di chuyển các mô-đun giữa các phân vùng. Nếu Hình ảnh hệ thống chung (GSI) được chỉ định, công cụ định nghĩa VNDK có thể so sánh hình ảnh hệ thống của bạn với GSI và xác định các thư viện mở rộng.

Phần này bao gồm ba lệnh được sử dụng thường xuyên cho công cụ định nghĩa VNĐK:

  • vndk . Tính toán VNĐK_SP_LIBRARIES, VNĐK_SP_EXT_LIBRARIES và EXTRA_VENDOR_LIBRARIES để xây dựng giải pháp hệ thống trong Android 8.0 trở lên.
  • check-dep . Kiểm tra các phần phụ thuộc mô-đun vi phạm từ mô-đun của nhà cung cấp đến thư viện chia sẻ khung không đủ điều kiện.
  • deps . In các phần phụ thuộc giữa các thư viện dùng chung và các tệp thực thi.

Để biết thêm chi tiết về cách sử dụng lệnh nâng cao, hãy tham khảo tệp README.md trong kho Công cụ định nghĩa VNĐK.

vndk

Lệnh con vndk tải các thư viện dùng chung và các tệp thực thi từ phân vùng hệ thống và phân vùng nhà cung cấp, sau đó giải quyết các phụ thuộc của mô-đun để xác định các thư viện phải được sao chép vào /system/lib[64]/vndk-sp-${VER}/vendor/lib[64] . Các tùy chọn cho lệnh con vndk bao gồm:

Lựa chọn Sự miêu tả
--system Trỏ tới thư mục chứa các tập tin sẽ nằm trong phân vùng hệ thống.
--vendor Trỏ tới thư mục chứa các tệp sẽ nằm trong phân vùng của nhà cung cấp.
--aosp-system Trỏ tới thư mục chứa các tệp sẽ nằm trong Hình ảnh Hệ thống Chung (GSI).
--load-extra-deps Trỏ tới một tệp mô tả các phần phụ thuộc tiềm ẩn, chẳng hạn như dlopen() .

Ví dụ: để tính toán bộ thư viện VNĐK, hãy chạy lệnh con vndk sau:

./vndk_definition_tool.py vndk \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor \
    --aosp-system ${ANDROID_PRODUCT_OUT}/../generic_arm64_ab/system\
    --load-extra-deps dlopen.dep

Chỉ định các phần phụ thuộc bổ sung bằng định dạng tệp đơn giản. Mỗi dòng thể hiện một mối quan hệ, với tệp trước dấu hai chấm tùy thuộc vào tệp sau dấu hai chấm. Ví dụ:

/system/lib/libart.so: /system/lib/libart-compiler.so

Dòng này cho công cụ định nghĩa VNĐK biết rằng libart.so phụ thuộc vào libart-compiler.so .

Đích cài đặt

Công cụ định nghĩa VNDK liệt kê các thư viện và thư mục cài đặt tương ứng cho các danh mục sau:

Loại Danh mục
vndk_sp Phải cài vào /system/lib[64]/vndk-sp-${VER}
vndk_sp_ext Phải cài vào /vendor/lib[64]/vndk-sp
extra_vendor_libs Phải cài đặt vào /vendor/lib[64]

Xây dựng mẫu hệ thống

Sau khi thu thập đầu ra từ công cụ định nghĩa VNDK, nhà cung cấp có thể tạo Android.mk và điền vào VNDK_SP_LIBRARIES , VNDK_SP_EXT_LIBRARIESEXTRA_VENDOR_LIBRARIES để tự động hóa quy trình sao chép thư viện đến đích cài đặt được chỉ định.

ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
VNDK_SP_LIBRARIES := ##_VNDK_SP_##
VNDK_SP_EXT_LIBRARIES := ##_VNDK_SP_EXT_##
EXTRA_VENDOR_LIBRARIES := ##_EXTRA_VENDOR_LIBS_##

#-------------------------------------------------------------------------------
# VNDK Modules
#-------------------------------------------------------------------------------
LOCAL_PATH := $(call my-dir)

define define-vndk-lib
include $$(CLEAR_VARS)
LOCAL_MODULE := $1.$2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
LOCAL_STRIP_MODULE := false
LOCAL_MULTILIB := first
LOCAL_MODULE_TAGS := optional
LOCAL_INSTALLED_MODULE_STEM := $1.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_RELATIVE_PATH := $3
LOCAL_VENDOR_MODULE := $4
include $$(BUILD_PREBUILT)

ifneq ($$(TARGET_2ND_ARCH),)
ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
include $$(CLEAR_VARS)
LOCAL_MODULE := $1.$2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PREBUILT_MODULE_FILE := $$($$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
LOCAL_STRIP_MODULE := false
LOCAL_MULTILIB := 32
LOCAL_MODULE_TAGS := optional
LOCAL_INSTALLED_MODULE_STEM := $1.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_RELATIVE_PATH := $3
LOCAL_VENDOR_MODULE := $4
include $$(BUILD_PREBUILT)
endif  # TARGET_TRANSLATE_2ND_ARCH is not true
endif  # TARGET_2ND_ARCH is not empty
endef

$(foreach lib,$(VNDK_SP_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-sp-gen,vndk-sp,)))
$(foreach lib,$(VNDK_SP_EXT_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-sp-ext-gen,vndk-sp,true)))
$(foreach lib,$(EXTRA_VENDOR_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-ext-gen,,true)))


#-------------------------------------------------------------------------------
# Phony Package
#-------------------------------------------------------------------------------

include $(CLEAR_VARS)
LOCAL_MODULE := $(YOUR_DEVICE_NAME)-vndk
LOCAL_MODULE_TAGS := optional
LOCAL_REQUIRED_MODULES := \
    $(addsuffix .vndk-sp-gen,$(VNDK_SP_LIBRARIES)) \
    $(addsuffix .vndk-sp-ext-gen,$(VNDK_SP_EXT_LIBRARIES)) \
    $(addsuffix .vndk-ext-gen,$(EXTRA_VENDOR_LIBRARIES))
include $(BUILD_PHONY_PACKAGE)

endif  # ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)

kiểm tra phòng

Lệnh con check-dep quét các mô-đun của nhà cung cấp và kiểm tra các phần phụ thuộc của chúng. Nếu phát hiện vi phạm, nó sẽ in thư viện phụ thuộc vi phạm và cách sử dụng ký hiệu:

./vndk_definition_tool.py check-dep \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor \
    --tag-file eligible-list.csv \
    --module-info ${ANDROID_PRODUCT_OUT}/module-info.json \
    1> check_dep.txt \
    2> check_dep_err.txt

Ví dụ: đầu ra mẫu sau đây cho thấy sự phụ thuộc vi phạm từ libRS_internal.so đến libmediandk.so :

/system/lib/libRS_internal.so
        MODULE_PATH: frameworks/rs
        /system/lib/libmediandk.so
                AImageReader_acquireNextImage
                AImageReader_delete
                AImageReader_getWindow
                AImageReader_new
                AImageReader_setImageListener

Các tùy chọn cho lệnh con check-dep bao gồm:

Lựa chọn Sự miêu tả
--tag-file Phải tham khảo tệp thẻ thư viện đủ điều kiện (được mô tả bên dưới), đây là bảng tính do Google cung cấp mô tả các danh mục thư viện chia sẻ khung.
--module-info Trỏ tới module-info.json do hệ thống xây dựng Android tạo ra. Nó giúp công cụ định nghĩa VNDK liên kết các module nhị phân với mã nguồn.

Tệp thẻ thư viện đủ điều kiện

Google cung cấp bảng tính VNĐK đủ điều kiện (ví dụ: eligible-list.csv ) để gắn thẻ các thư viện dùng chung khung mà các mô-đun của nhà cung cấp có thể sử dụng:

Nhãn Sự miêu tả
LL-NDK Thư viện dùng chung với ABI/API ổn định có thể được sử dụng bởi cả mô-đun khung và nhà cung cấp.
LL-NDK-Riêng tư Sự phụ thuộc riêng tư của thư viện LL-NDK. Các mô-đun của nhà cung cấp không được truy cập trực tiếp vào các thư viện này.
VNĐK-SP Các phần phụ thuộc của thư viện chia sẻ khung SP-HAL.
VNĐK-SP-Private Các phần phụ thuộc của VNDK-SP không thể truy cập trực tiếp vào tất cả các mô-đun của nhà cung cấp.
VNĐK Thư viện chia sẻ khung có sẵn cho các mô-đun của nhà cung cấp (ngoại trừ SP-HAL và SP-HAL-Dep).
VNĐK-Private Các phụ thuộc VNĐK không thể truy cập trực tiếp vào tất cả các mô-đun của nhà cung cấp.
CHỈ FWK Các thư viện chia sẻ chỉ dành cho khung mà các mô-đun của nhà cung cấp không được truy cập (trực tiếp hay gián tiếp).
FWK-CHỈ-RS Các thư viện chia sẻ chỉ dành cho khung mà các mô-đun của nhà cung cấp không được truy cập (ngoại trừ việc sử dụng RS).

Bảng sau mô tả các thẻ được sử dụng cho thư viện chia sẻ của nhà cung cấp:

Nhãn Sự miêu tả
SP-HAL Thư viện chia sẻ triển khai HAL cùng quy trình.
SP-HAL-Dep Các phần phụ thuộc thư viện chia sẻ của nhà cung cấp SP-HAL (hay còn gọi là phần phụ thuộc SP-HAL không bao gồm LL-NDK và VNDK-SP).
CHỈ VNĐ Các thư viện chia sẻ không nhìn thấy được trong khung mà các mô-đun khung không được truy cập. Các thư viện VNĐK mở rộng được sao chép cũng sẽ được gắn thẻ là CHỈ VNĐ.

Mối quan hệ giữa các thẻ:

Mối quan hệ giữa các thẻ.
Hình 1. Mối quan hệ giữa các thẻ.

phụ thuộc

Để gỡ lỗi các phần phụ thuộc của thư viện, lệnh con deps sẽ in các phần phụ thuộc của mô-đun:

./vndk_definition_tool.py deps \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor

Đầu ra bao gồm nhiều dòng. Dòng không có ký tự tab sẽ bắt đầu một phần mới. Dòng có ký tự tab phụ thuộc vào phần trước. Ví dụ:

/system/lib/ld-android.so
/system/lib/libc.so
        /system/lib/libdl.so

Kết quả đầu ra này cho thấy ld-android.so không có phần phụ thuộc và libc.so phụ thuộc vào libdl.so .

Khi chỉ định tùy chọn --revert , tiểu lệnh deps sẽ in cách sử dụng của các thư viện (phụ thuộc đảo ngược):

./vndk_definition_tool.py deps \
    --revert \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor

Ví dụ:

/system/lib/ld-android.so
        /system/lib/libdl.so
        

Kết quả đầu ra này cho thấy ld-android.so được sử dụng bởi libdl.so , hay nói cách khác, libdl.so phụ thuộc vào ld-android.so . Ngoài ra, kết quả đầu ra này cho thấy libdl.so là người dùng duy nhất của ld-android.so .

Khi chỉ định tùy chọn --symbol , lệnh phụ deps sẽ in các ký hiệu đang được sử dụng:

./vndk_definition_tool.py deps \
    --symbol \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor
    

Ví dụ:

/system/lib/libc.so
        /system/lib/libdl.so
                android_get_application_target_sdk_version
                dl_unwind_find_exidx
                dlclose
                dlerror
                dlopen
                dlsym

Đầu ra này cho thấy libc.so phụ thuộc vào 6 hàm được xuất từ libdl.so . Nếu cả tùy chọn --symbol và tùy chọn --revert đều được chỉ định, các ký hiệu mà người dùng sử dụng sẽ được in.