באנדרואיד 8.1 ומעלה, למערכת הבנייה יש תמיכה מובנית ב-VNDK. כאשר תמיכת VNDK מופעלת, מערכת הבנייה בודקת את התלות בין המודולים, בונה גרסה ספציפית לספק עבור מודולי ספקים, ומתקינה באופן אוטומטי את המודולים הללו בספריות ייעודיות.
דוגמה לתמיכה בבניית VNDK
בדוגמה זו, הגדרת המודול Android.bp
מגדירה ספרייה בשם libexample
. המאפיין vendor_available
מציין מודולי מסגרת ומודולי ספק עשויים להיות תלויים ב- libexample
:
גם קובץ ההפעלה /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
.
לפרטים נוספים, ראה הגדרת מודול .
הגדרת תמיכת בנייה
כדי לאפשר תמיכת מערכת בנייה מלאה עבור התקן מוצר, הוסף את 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 משוטח או לא משטח וזמין מהנתיב הקנוני /apex/com.android.vndk.v${VER}
.
הגדרת מודול
כדי לבנות אנדרואיד עם BOARD_VNDK_VERSION
, עליך לשנות את הגדרת המודול ב- Android.mk
או Android.bp
. סעיף זה מתאר סוגים שונים של הגדרות מודול, מספר מאפייני מודול הקשורים ל-VNDK ובדיקות תלות המיושמות במערכת הבנייה.
מודולים של ספקים
מודולי ספק הם קובצי הפעלה ספציפיים לספק או ספריות משותפות שיש להתקין במחיצת ספק. בקבצי Android.bp
, מודולי ספק חייבים להגדיר את הספק או המאפיין הקנייני ל- true
. בקבצי Android.mk
, מודולי הספק חייבים להגדיר את LOCAL_VENDOR_MODULE
או LOCAL_PROPRIETARY_MODULE
ל- true
.
אם BOARD_VNDK_VERSION
מוגדרת, מערכת ה-build אוסרת תלות בין מודולי ספק ומודול מסגרת ופולטת שגיאות אם:
- מודול ללא
vendor:true
תלוי במודול עםvendor:true
, או - מודול עם
vendor:true
תלוי במודול non-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 הן ספריות משותפות עם ABI יציבים. גם מודולי המסגרת וגם המודולים של הספק חולקים את אותו היישום והיישום העדכני ביותר. עבור כל ספרייה משותפת של LL-NDK, ה- cc_library
מכיל מאפיין llndk
עם קובץ סמלים:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
קובץ הסמלים מתאר את הסמלים הנראים למודולי הספק. לדוגמה:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
בהתבסס על קובץ הסמלים, מערכת ה-build מייצרת ספרייה משותפת של קטעים עבור מודולי ספקים, אשר מקשרים עם ספריות אלו כאשר 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}
).
- אם
הטבלה שלהלן מסכמת כיצד מערכת הבנייה מטפלת בגרסאות הספק:
vendor_available | vndk מופעל | vndk support_same_process | תיאורי וריאציות של ספקים |
---|---|---|---|
true | false | false | גרסאות הספק הן VND בלבד . ספריות משותפות מותקנות ב- /vendor/lib[64] . |
true | לא חוקי (שגיאת בנייה) | ||
true | false | גרסאות הספק הן VNDK . ספריות משותפות מותקנות ב-VNDK APEX. | |
true | גרסאות הספק הן VNDK-SP . ספריות משותפות מותקנות ב-VNDK APEX. | ||
| | | אין גרסאות של ספקים. מודול זה מיועד ל-FWK בלבד . |
true | לא חוקי (שגיאת בנייה) | ||
true | false | גרסאות הספק הן VNDK-Private . ספריות משותפות מותקנות ב-VNDK APEX. אין להשתמש בהם ישירות על ידי מודולי הספק. | |
true | גרסאות הספק הן VNDK-SP-Private . ספריות משותפות מותקנות ב-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
אם מודול ספק תלוי בממשקי API נוספים שהוגדרו על ידי הרחבות 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:
- גרסת ליבה (למשל
/system/lib[64]/libexample.so
) - וריאנט ספק (למשל
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) - סיומת VNDK (למשל
/vendor/lib[64]/vndk[-sp]/libexample.so
)
דגלי מהדר מותנים
מערכת ה-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 |
דרישות על הסמלים המיוצאים
בודק VNDK ABI משווה את ה-ABI של גרסאות הספק של VNDK והרחבות VNDK ל-ABI dumps הייחוס תחת prebuilts/abi-dumps/vndk
.
- סמלים המיוצאים על ידי גרסאות של ספקים של VNDK (למשל
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) חייבים להיות זהים לסמלים המוגדרים ב-ABI dumps (לא לערכות העל של ה-VNDK). - סמלים המיוצאים על ידי הרחבות VNDK (למשל
/vendor/lib[64]/vndk/libexample.so
) חייבים להיות ערכות-על של הסמלים המוגדרים ב-ABI dumps.
אם גרסאות הספק של 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
- include/example/example.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
guards. עם זאת, ודא שכל משתמשי תוסף VNDK מוסיפים את הדגלים המגדירים. אתה יכול להגדיר cc_defaults
כדי להוסיף דגלים להגדיר ל- cflags
ולקשר ספריות משותפות עם shared_libs
.
לדוגמה, כדי להוסיף פונקציית חבר חדשה Example2::get_b()
לסיומת VNDK libexample2_ext
, עליך לשנות את קובץ הכותרת הקיים ולהוסיף #ifdef
guard:
#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, }
חבילות מוצרים
במערכת ה-build של Android, המשתנה PRODUCT_PACKAGES
מציין את קובצי ההפעלה, הספריות המשותפות או החבילות שיש להתקין במכשיר. התלות הטרנזיטיבית של המודולים שצוינו מותקנות במרומז גם במכשיר.
אם BOARD_VNDK_VERSION
מופעל, מודולים עם vendor_available
או vndk.enabled
מקבלים טיפול מיוחד. אם מודול מסגרת תלוי במודול עם vendor_available
או vndk.enabled
, גרסת הליבה כלולה בערכת ההתקנה הטרנזיטיבית. אם מודול ספק תלוי במודול עם vendor_available
, גרסת הספק כלולה בערכת ההתקנה הטרנזיטיבית. עם זאת, גרסאות ספק של מודולים עם vndk.enabled
מותקנים בין אם הם משמשים על ידי מודולי ספק ובין אם לא.
כאשר התלות אינן נראות למערכת ה-build (למשל ספריות משותפות שעשויות להיפתח עם 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