תמיכה במערכת VNDK Build

ב- Android 8.1 ואילך, מערכת ה- build כוללת תמיכה מובנית ב- VNDK. כאשר תמיכה ב- VNDK מופעלת, מערכת הבנייה בודקת את התלות בין המודולים, בונה גרסה ספציפית לספק עבור מודולי ספק ומתקינה אוטומטית את המודולים האלה בספריות ייעודיות.

דוגמא לתמיכה ב- VNDK build

בדוגמה זו, Android.bp הגדרת המודול מגדיר בשם הספרייה libexample . vendor_available יציין מודולים במסגרת ומודולים ספק עשויים להיות תלוי libexample :

libexample vendor_available: true ו- vndk.enabled: true

תמיכה איור 1. VNDK מופעלת

שניהם במסגרת ההפעלה /system/bin/foo לבין הספק הפעלה /vendor/bin/bar תלוי libexample ויש libexample ב שלהם shared_libs נכסים.

אם libexample משמש הן מודולים במסגרת ומודולים הספק, שתי גרסאות של libexample בנויים. גרסת הליבה (שמה libexample ) משמשת מודולים מסגרת גרסת הספק (שמה libexample.vendor ) משמשת מודולים ספק. שתי הגרסאות מותקנות בספריות שונות:

  • גרסת הליבה מותקנת לתוך /system/lib[64]/libexample.so .
  • הגרסה הספק מותקן לתוך VNDK APEX כי vndk.enabled הוא true .

לפרטים נוספים, ראה הגדרת מודול .

הגדרת תמיכת build

כדי לאפשר תמיכה במערכת לבנות מלאה עבור מכשיר מוצר, להוסיף BOARD_VNDK_VERSION כדי BoardConfig.mk :

BOARD_VNDK_VERSION := current

יש הגדרה זו השפעה גלובלית: כאשר שהוגדרו BoardConfig.mk , כל המודולים נבדקים. מאחר ואין מנגנון לרשימה השחורה או הלבנה מודול הפוגע, אתה צריך לנקות את כל תלות מיותרת לפני הוספת BOARD_VNDK_VERSION . אתה יכול לבדוק ולעבד מודול ידי הגדרת BOARD_VNDK_VERSION ב משתנה הסביבה שלך:

$ BOARD_VNDK_VERSION=current m module_name.vendor

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

  • 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

אם מודול תלוי כותרות מספריות אלה, אתה חייב לציין (במפורש) את יחסי התלות עם header_libs , static_libs , ו / או shared_libs .

VNDK APEX

בשנת אנדרואיד 10 ומטה, מודולים עם vndk.enabled הותקנו /system/lib[64]/vndk[-sp]-${VER} . בשנת אנדרואיד 11 ומעלה, ספריות VNDK נארזים בתבנית APEX ואת השם של VNDK APEX הוא com.android.vndk.v${VER} . בהתאם לתצורת המכשיר, VNDK APEX הוא שטוח או unflattened והוא זמין מנתיב הקנונית /apex/com.android.vndk.v${VER} .

VNDK APEX

איור 2. VNDK APEX

הגדרת מודול

כדי לבנות אנדרואיד עם BOARD_VNDK_VERSION , אתה חייב לשנות את הגדרת המודול באחת Android.mk או Android.bp . חלק זה מתאר סוגים שונים של הגדרות מודול, מספר מאפייני מודול הקשורים ל- VNDK, ובדיקות תלות המיושמות במערכת הבנייה.

מודולי ספקים

מודולי ספקים הם הפעלות ספציפיות לספק או ספריות משותפות שיש להתקין במחיצת ספק. בשנת Android.bp קבצים, מודולים ספק חייבים להגדיר הספק או נכס קניינים כדי true . בשנת Android.mk קבצים, מודולים ספק חייבים להגדיר LOCAL_VENDOR_MODULE או LOCAL_PROPRIETARY_MODULE כדי true .

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

  • מודול ללא vendor:true תלוי מודול עם vendor:true , או
  • מודול עם vendor:true תלוי שאינו llndk_library מודול שאין לו vendor:true ולא vendor_available:true .

בדיקת התלות חל header_libs , static_libs , ו shared_libs ב Android.bp , וכדי LOCAL_HEADER_LIBRARIES , LOCAL_STATIC_LIBRARIES ו LOCAL_SHARED_LIBRARIES ב Android.mk .

LL-NDK

ספריות משותפות LL-NDK הן ספריות משותפות עם ABIs יציבים. שני מודולי המסגרת והספק חולקים את אותו ההטמעה והיישום האחרון. עבור כל LL-NDK בספרייה משותפת, Android.bp מכיל llndk_library הגדרת המודול:

llndk_library {
    name: "libvndksupport",
    symbol_file: "libvndksupport.map.txt",
}

הגדרת מודול זו מציינת שם מודול וקובץ סמל המתאר את הסמלים הנראים למודולי ספקים. לדוגמה:

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

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

  • אינו מוגדר בסוף הקטע עם _PRIVATE או _PLATFORM ,
  • האם אין #platform-only תג, ו
  • האם אין #introduce* תגים או גפרורי תג עם היעד.

VNDK

בשנת Android.bp קבצים, cc_library , cc_library_static , cc_library_shared , ו cc_library_headers מודול ההגדרות לתמוך שלוש תכונות הקשורות VNDK: vendor_available , vndk.enabled , ו vndk.support_system_process .

אם vendor_available או vndk.enabled הוא true , שתי הגירסות (ליבת ספק) ניתן לבנות. יש להתייחס לגרסת הליבה כמודול מסגרת ולגישת הספק כמודול ספק. אם כמה מודולי מסגרת תלויים במודול זה, גרסת הליבה בנויה. אם מודולי ספק מסוימים תלויים במודול זה, גרסת הספק בנויה. מערכת ה- build אוכפת את בדיקות התלות הבאות:

  • גרסת הליבה היא תמיד למסגרת בלבד ובלתי נגישה למודולי ספקים.
  • גרסת הספק תמיד אינה נגישה למודולי מסגרת.
  • כל תלות של וריאנט הספק, אשר מפורטים header_libs , static_libs , ו / או shared_libs , חייב להיות שם של llndk_library או מודול עם vendor_available או vndk.enabled .
  • אם vendor_available הוא true , גרסת ההספק נגישה לכול המודולים הספק.
  • אם vendor_available היא false , גרסת ההספק נגישה רק כדי VNDK האחר או מודולים VNDK-SP (כלומר, מודולים עם vendor:true לא ניתן לקשר vendor_available:false מודולים).

נתיב התקנת ברירת מחדל עבור cc_library או cc_library_shared נקבע על פי הכללים הבאים:

  • גרסת הליבה מותקנת /system/lib[64] .
  • נתיב ההתקנה של גרסת הספק עשוי להשתנות:
    • אם vndk.enabled הוא false , גרסת ההספק מותקנת לתוך /vendor/lib[64] .
    • אם vndk.enabled הוא true , גרסת ההספק מותקנת לתוך VNDK APEX ( com.android.vndk.v${VER} ).

הטבלה שלהלן מסכמת את האופן שבו מערכת ה- build מטפלת בגרסאות הספק:

vendor_available vndk
מופעל
vndk
support_same_process
תיאורי גרסאות ספק
true false false וריאנטים הספק הם VND בלבד. ספריות משותפות מותקנות לתוך /vendor/lib[64] .
true לא תקף (שגיאת Build)
true false וריאנטים הספק הם VNDK. ספריות משותפות מותקנות ב- VNDK APEX.
true וריאנטים הספק הם VNDK-SP. ספריות משותפות מותקנות ב- VNDK APEX.

false

false

false

אין גרסאות ספק. מודול זה הוא FWK בלבד.

true לא תקף (שגיאת Build)
true false וריאנטים הספק הם VNDK-פרטיים. ספריות משותפות מותקנות ב- VNDK APEX. אסור להשתמש במודולים של ספקים ישירות באלה.
true וריאנטים הספק הם VNDK-SP-פרטי. ספריות משותפות מותקנות ב- VNDK APEX. אסור להשתמש במודולים של ספקים ישירות באלה.

הרחבות VNDK

הרחבות VNDK הן ספריות משותפות של VNDK עם ממשקי API נוספים. רחבות מותקנות כדי /vendor/lib[64]/vndk[-sp] (ללא סיומת גרסה) ו לדרוס את המקורי VNDK משותף ספריות בזמן הריצה.

הגדרת תוספי VNDK

בשנת אנדרואיד 9 ומעלה, Android.bp התומך בהרחבות VNDK מקורי. כדי לבנות רחבת VNDK, להגדיר מודול אחר עם vendor:true וגם extends רכוש:

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

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

מודול בעל vendor:true , vndk.enabled:true , וגם extends מאפיינים מגדירים את סיומת VNDK:

  • extends נכס חייב לציין בסיס VNDK משותף שם הספרייה (או VNDK-SP משותף שם הספרייה).
  • הרחבות VNDK (או הרחבות VNDK-SP) נקראות על שם שמות המודולים הבסיסיים מהם הם נמשכים. לדוגמה, בינארי הפלט של libvndk_ext הוא libvndk.so במקום libvndk_ext.so .
  • רחבות VNDK מותקנות לתוך /vendor/lib[64]/vndk .
  • רחבות VNDK-SP מותקנות לתוך /vendor/lib[64]/vndk-sp .
  • הספריות משותפות הבסיס חייבות להיות שניהם vndk.enabled:true ו vendor_available:true .

קיימת אפשרות להרחבת VNDK-SP חייב להאריך מספריה VNDK-SP משותף ( vndk.support_system_process חייב להיות שווה):

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

תוספי VNDK (או הרחבות VNDK-SP) עשויים להיות תלויים בספריות משותפות של ספקים:

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

שימוש בתוספי VNDK

אם מודול הספק תלוי APIs נוספים שהוגדרו על ידי הרחבות VNDK, מודול חייב לציין את שמו של הרחבה VNDK ב שלו 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",
    ],
}

אם מודול הספק תלוי רחבות VNDK, אלה רחבות VNDK מותקנות כדי /vendor/lib[64]/vndk[-sp] באופן אוטומטי. אם מודול כבר לא תלוי רחבת VNDK, להוסיף צעד נקי CleanSpec.mk להסיר את הספרייה המשותפת. לדוגמה:

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

אוסף מותנה

סעיף זה מתאר כיצד להתמודד עם ההבדלים הדקים (למשל הוספה או סר של תכונה מאחת הגירסות) בין הבא השלושה VNDK משותף ספריות:

  • וריאנט Core (למשל /system/lib[64]/libexample.so )
  • וריאנט Vendor (למשל /apex/com.android.vndk.v${VER}/lib[64]/libexample.so )
  • הארכת VNDK (למשל /vendor/lib[64]/vndk[-sp]/libexample.so )

דגלי מהדר מותנים

מערכת Android Build מגדיר __ANDROID_VNDK__ עבור גרסאות הספק והרחבות VNDK כברירת מחדל. תוכל לשמור על הקוד עם שומרי המעבד C:

void all() { }

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

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

בנוסף __ANDROID_VNDK__ , שונה cflags או cppflags עשוי להיות מצוין Android.bp . cflags או cppflags המפורטים target.vendor הוא ספציפי וריאנט הספק.

לדוגמה, את הדברים הבאים Android.bp מגדיר libexample ו 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",
    ],
}

וזה קוד הרישום של 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

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

נתיב התקנה סמלים מיוצאים
/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

דרישות לגבי הסמלים המיוצאים

בודק ABI VNDK משווה את הספק ABI של VNDK וריאנטים והרחבות VNDK להתייחסות ABI מרוקן תחת prebuilts/abi-dumps/vndk .

  • סמלים מיוצאים על ידי גרסות ספק VNDK (למשל /apex/com.android.vndk.v${VER}/lib[64]/libexample.so ) חייבים להיות זהים (לא supersets של) הסמלים שהוגדרו ABI המרוקנים.
  • סמלים מיוצאים על ידי רחבות VNDK (למשל /vendor/lib[64]/vndk/libexample.so ) חייבים להיות supersets של הסימנים שהוגדרו ABI המרוקנים.

אם הספק VNDK גרסאות או הרחבות VNDK מצליחים לבצע את הדרישות הנ"ל, פולט בודק VNDK ABI לבנות שגיאות ועוצר לבנות.

אי הכללת קבצי מקור או ספריות משותפות מגרסאות ספק

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

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

בדוגמא זו, גרסת הליבה של libexample_cond_exclude כוללת את קוד fwk.c ו both.c ותלוי הספריות המשותפות libfwk_only ו libboth . גרסת הספק של libexample_cond_exclude כוללת רק את קוד both.c בגלל fwk.c נשלל על ידי exclude_srcs הרכוש. בדומה לכך, זה תלוי בספריה המשותפת רק libboth בגלל libfwk_only נשלל על ידי exclude_shared_libs רכוש.

ייצא כותרות מתוספי VNDK

סיומת VNDK עשויה להוסיף שיעורים חדשים או פונקציות חדשות לספרייה משותפת של VNDK. מוצע לשמור את ההצהרות האלה בכותרות עצמאיות ולהימנע משינוי הכותרות הקיימות.

לדוגמא, קובץ כותרת חדש include-ext/example/ext/feature_name.h נוצר עבור הארכת VNDK libexample_ext :

  • Android.bp
  • include-ext/example/ext/feature_name.h
  • כלול/דוגמא/דוגמה.ה
  • src/example.c
  • src/ext/feature_name.c

בחודש הבא Android.bp , libexample ייצוא רק include , ואילו libexample_ext ייצוא הוא include ו include-ext . מבטיחה זו feature_name.h לא תיכלל באופן שגוי על ידי המשתמשים של 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",
    },
}

אם הפרדת סיומות לקבצי כותרת עצמאיות הוא לא ריאלי, אלטרנטיבה היא להוסיף #ifdef שומרים. עם זאת, ודא שכל משתמשי תוספי VNDK מוסיפים את דגלי ההגדרה. אתה יכול להגדיר cc_defaults להוסיף להגדיר דגלים כדי cflags וספריות משותפות קישור עם shared_libs .

לדוגמה, כדי להוסיף פונקציה חברה חדשה Example2::get_b() הארכת VNDK libexample2_ext , עליך לשנות את קובץ הכותרת הקיים ולהוסיף #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 בשם libexample2_ext_defaults מוגדר עבור משתמשים של 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",
    ],
}

המשתמשים של libexample2_ext להכליל libexample2_ext_defaults ב שלהם defaults רכוש:

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

חבילות מוצרים

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

אם BOARD_VNDK_VERSION מופעלת, מודולים עם vendor_available או vndk.enabled לקבל טיפול מיוחד. אם מודול מסגרת תלוי מודול עם vendor_available או vndk.enabled , גרסת הליבה כלול בערכת ההתקנה טרנזיטיבית. אם מודול הספק תלוי מודול עם vendor_available , גרסת ההספק כלול בערכת ההתקנה טרנזיטיבית. עם זאת, ספק וריאנטים של מודולים עם vndk.enabled מותקנים אם הם נמצאים בשימוש על ידי מודולים ספק.

כאשר התלות אינן נראות המערכות בונות (למשל משותפת ספריות כי ניתן לפתוח עם dlopen() ב ריצה), אתה צריך לציין את שמות מודול ב PRODUCT_PACKAGES להתקין מודולים אלו במפורש.

אם מודול יש vendor_available או vndk.enabled , שם המודול מייצג גרסת הליבה שלה. כדי לציין את גרסת ספק במפורש PRODUCT_PACKAGES , לצרף .vendor סיומת שם המודול. לדוגמה:

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

בדוגמה זו, libexample מייצג /system/lib[64]/libexample.so ו libexample.vendor מייצג /vendor/lib[64]/libexample.so . כדי להתקין /vendor/lib[64]/libexample.so , להוסיף libexample.vendor כדי PRODUCT_PACKAGES :

PRODUCT_PACKAGES += libexample.vendor