כלי להגדרת 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 Definition Tool.

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 שנוצר על ידי מערכת build של Android. הוא עוזר לכלי ההגדרה של VNDK לשייך מודולים בינאריים לקוד מקור.

קובץ תג ספרייה כשיר

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

תיוג תיאור
LL-NDK ספריות משותפות עם ממשקי API או ABI יציבים שאפשר להשתמש בהם גם במודולים של המסגרת וגם במודולים של הספק.
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 ספריות משותפות ל-Framework בלבד, שאסור למודולים של ספקים לגשת אליהן (לא באופן ישיר ולא באופן עקיף).
FWK-ONLY-RS ספריות משותפות ל-Framework בלבד, שאסור למודולים של ספקים לגשת אליהן (למעט לשימוש ב-RS).

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

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

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

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

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

deps

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

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

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

/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, המערכת מדפיסה את הסמלים שבהם המשתמש משתמש.