כלי להגדרת VNDK

הכלי להגדרת VNDK עוזר לספקים להעביר את עץ המקור שלהם לסביבת Android 8.0. הכלי הזה סורק קבצים בינאריים במערכת ובדימויים של הספקים, ואז פותר את התלות. על סמך גרף התלות של המודול, הכלי יכול גם לזהות הפרות של מושגי VNDK ולספק תובנות או הצעות להעברת מודולים בין מחיצות. אם מציינים תמונת מערכת גנרית (GSI), כלי ההגדרה של VNDK יכול להשוות את תמונת המערכת שלכם ל-GSI ולקבוע את הספריות המורחבות.

בקטע הזה מוסבר על שלוש פקודות נפוצות לשימוש בכלי להגדרת VNDK:

  • vndk. חישוב של VNDK_SP_LIBRARIES,‏ VNDK_SP_EXT_LIBRARIES ו-EXTRA_VENDOR_LIBRARIES לעקיפת בעיה במערכת build ב-Android מגרסה 8.0 ואילך.
  • check-dep. בודקים את התלויות של המודולים שמפירים את המדיניות, ממודולים של ספקים לספריות משותפות של מסגרות שלא עומדות בדרישות.
  • deps. הדפסת התלויות בין הספריות המשותפות וקבצי ההפעלה.

לפרטים נוספים על שימוש מתקדם בפקודות, אפשר לעיין בקובץ README.md במאגר של כלי ההגדרה של VNDK.

vndk

פקודת המשנה vndk טוענת את הספריות המשותפות ואת קובצי ההפעלה ממחיצת המערכת וממחיצות הספק, ואז פותרת את התלות של המודולים כדי לקבוע אילו ספריות צריך להעתיק אל /system/lib[64]/vndk-sp-${VER} ואל /vendor/lib[64]. האפשרויות לפקודת המשנה vndk כוללות:

אפשרות תיאור
--system מציינים ספרייה שמכילה את הקבצים שנמצאים במחיצת המערכת.
--vendor מצביעים על ספרייה שמכילה את הקבצים שנמצאים במחיצה של ספק.
--aosp-system מצביעים על ספרייה שמכילה את הקבצים שנמצאים בתמונת המערכת הגנרית (GSI).
--load-extra-deps מציינים קובץ שמתאר את יחסי התלות המרומזים, למשל dlopen().

לדוגמה, כדי לחשב את קבוצות הספריות של VNDK, מריצים את פקודת המשנה vndk הבאה:

./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

אפשר לציין תלויות נוספות באמצעות פורמט קובץ פשוט. כל שורה מייצגת קשר, כאשר הקובץ לפני הנקודתיים תלוי בקובץ אחרי הנקודתיים. לדוגמה:

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

השורה הזו מאפשרת לכלי להגדרת VNDK לדעת ש-libart.so תלוי ב-libart-compiler.so.

יעד ההתקנה

כלי ההגדרה של VNDK מפרט ספריות וספריות התקנה תואמות לקטגוריות הבאות:

קטגוריה ספרייה
vndk_sp חובה להתקין ב-/system/lib[64]/vndk-sp-${VER}
vndk_sp_ext חובה להתקין ב-/vendor/lib[64]/vndk-sp
extra_vendor_libs חובה להתקין ב-/vendor/lib[64]

תבניות של מערכת build

אחרי איסוף הפלט מכלי ההגדרה של VNDK, ספק יכול ליצור Android.mk ולמלא את VNDK_SP_LIBRARIES,‏ VNDK_SP_EXT_LIBRARIES ו-EXTRA_VENDOR_LIBRARIES כדי להפוך את התהליך לאוטומטי ולהעתיק ספריות ליעד ההתקנה שצוין.

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

check-dep

פקודת המשנה check-dep סורקת מודולים של ספקים ובודקת את התלויות שלהם. אם הוא מזהה הפרות, הוא מדפיס את השימושים בספרייה התלויה ובסמל שמפירים את המדיניות:

./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

לדוגמה, בפלט הבא מוצגת תלות שמפרה את הכללים מ-libRS_internal.so ל-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

האפשרויות לפקודת המשנה check-dep כוללות:

אפשרות תיאור
--tag-file התג חייב להתייחס לקובץ תג ספרייה שעומד בדרישות (מתואר בהמשך), שהוא גיליון אלקטרוני שסופק על ידי Google ומתאר קטגוריות של ספריות משותפות של מסגרות.
--module-info מצביע על module-info.json שנוצר על ידי מערכת Android build. הוא עוזר לכלי להגדרת VNDK לשייך מודולים בינאריים לקוד המקור.

קובץ תג ספרייה שעומד בדרישות

‫Google מספקת גיליון אלקטרוני מתאים של VNDK (לדוגמה: eligible-list.csv) שמתייג את הספריות המשותפות של המסגרת שאפשר להשתמש בהן במודולים של הספק:

תיוג תיאור
LL-NDK ספריות משותפות עם ממשקי ABI/API יציבים שאפשר להשתמש בהם גם במודולים של מסגרות וגם במודולים של ספקים.
LL-NDK-Private יחסי תלות פרטיים של ספריות LL-NDK. אסור למודולים של ספקים לגשת לספריות האלה ישירות.
VNDK-SP תלויות בספריות משותפות של מסגרת SP-HAL.
VNDK-SP-Private תלויות ב-VNDK-SP שלא נגישות ישירות לכל המודולים של הספק.
VNDK ספריות משותפות של מסגרות שזמינות למודולים של ספקים (חוץ מ-SP-HAL ו-SP-HAL-Dep).
VNDK-Private תלויות ב-VNDK שלא נגישות ישירות לכל המודולים של הספק.
FWK-ONLY ספריות משותפות שמבוססות על מסגרת בלבד, שאסור למודולים של ספקים לגשת אליהן (לא באופן ישיר ולא באופן עקיף).
FWK-ONLY-RS ספריות משותפות שמבוססות על Framework בלבד, שאסור למודולים של ספקים לגשת אליהן (למעט שימושים ב-RS).

בטבלה הבאה מתוארים תגים שמשמשים לספריות משותפות של ספקים:

תיוג תיאור
SP-HAL ספריות משותפות של יישומי HAL באותו תהליך.
SP-HAL-Dep תלויות של ספריות משותפות של ספקי SP-HAL (נקראות גם תלויות SP-HAL, לא כולל LL-NDK ו-VNDK-SP).
VND-ONLY ספריות משותפות שלא נראות למסגרת, שאסור לגשת אליהן ממודולים של המסגרת. גם הספריות המורחבות של VNDK שהועתקו מתויגות כ-VND-ONLY.

הקשרים בין התגים:

הקשרים בין התגים.

איור 1. הקשרים בין התגים.

deps

כדי לנפות באגים בתלויות של הספרייה, פקודת המשנה deps מדפיסה את התלויות של המודול:

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

הפלט מורכב מכמה שורות. השורה בלי תו הכרטיסייה מתחילה קטע חדש. השורה עם תו ה-Tab תלויה בקטע הקודם. לדוגמה:

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

בפלט הזה אפשר לראות של-ld-android.so אין תלות, ושל-libc.so יש תלות ב-libdl.so.

כשמציינים את האפשרות --revert, פקודת המשנה deps מדפיסה את השימושים בספריות (תלויות הפוכות):

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

לדוגמה:

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

הפלט הזה מראה ש-ld-android.so נמצא בשימוש על ידי libdl.so, או במילים אחרות, libdl.so תלוי ב-ld-android.so. בנוסף, מהפלט הזה אפשר לראות ש-libdl.so הוא המשתמש היחיד ב-ld-android.so.

כשמציינים את האפשרות --symbol, פקודת המשנה deps מדפיסה את הסמלים שבהם נעשה שימוש:

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

לדוגמה:

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

מהפלט הזה אפשר לראות שהפונקציה libc.so תלויה בשש פונקציות שמיוצאות מ-libdl.so. אם מציינים גם את האפשרות --symbol וגם את האפשרות --revert, המערכת מדפיסה את הסמלים שבהם המשתמש השתמש.