מערכת ה-build תומכת ביצירת קבצים בינאריים לשתי ארכיטקטורות של מעבדים (CPU) ייעודיים, 32 ביט ו-64 ביט, באותו build. הגרסה הזו עם שני היעדים נקראת build של multilib.
עבור ספריות סטטיות מובנות וספריות משותפות, מערכת ה-build מגדירה כללים ליצירת קובצי בינארי בשתי הארכיטקטורות. הגדרות המוצר (PRODUCT_PACKAGES
) יחד עם תרשים יחסי התלות קובעים אילו קובצי בינארי ייוצרו ויוטמעו בקובץ האימג' של המערכת.
לגבי קובצי הפעלה ואפליקציות, מערכת ה-build יוצרת רק את הגרסה ל-64 ביט כברירת מחדל, אבל אפשר לשנות את ההגדרה הזו באמצעות משתנה BoardConfig.mk
גלובלי או משתנה ברמת המודול.
זיהוי ארכיטקטורה ו-ABI של מעבד שני
BoardConfig.mk
כולל את המשתנים הבאים להגדרת הארכיטקטורה השנייה של המעבד ואת ממשק ה-Application Binary Interface (ABI):
TARGET_2ND_ARCH
TARGET_2ND_ARCH_VARIANT
TARGET_2ND_CPU_VARIANT
TARGET_2ND_CPU_ABI
TARGET_2ND_CPU_ABI2
דוגמה לקובץ makefile שמשתמש במשתנים האלה מופיעה בקובץ build/make/target/board/generic_arm64/BoardConfig.mk
.
ב-build של multilib, שמות המודולים ב-PRODUCT_PACKAGES
מכסים גם את הקבצים הבינאריים של 32 סיביות וגם את הקבצים הבינאריים של 64 סיביות, כל עוד הם מוגדרים על ידי מערכת ה-build. בספריות שכלולות ביחסי תלות, ספרייה של 32 או 64 סיביות מותקנת רק אם היא נדרשת על ידי ספרייה או קובץ הפעלה אחרים של 32 או 64 סיביות.
עם זאת, שמות המודולים בשורת הפקודה make
מכסים רק את הגרסה של 64 ביט. לדוגמה, אחרי שמריצים את lunch aosp_arm64-eng
, הפקודה make libc
יוצרת רק את libc של 64 ביט. כדי ליצור את libc של 32 ביט, מריצים את make libc_32
.
הגדרת ארכיטקטורת המודול בקובץ Android.mk
אפשר להשתמש במשתנה LOCAL_MULTILIB
כדי להגדיר את ה-build ל-32 ביט ול-64 ביט ולשנות את ברירת המחדל של המשתנה הגלובלי TARGET_PREFER_32_BIT
.
כדי לשנות את TARGET_PREFER_32_BIT
, מגדירים את LOCAL_MULTILIB
לאחת מהאפשרויות הבאות:
both
יוצר גרסאות build ב-32 ביט וב-64 ביט.32
יוצר רק 32 ביט.64
יוצר רק גרסת build של 64 ביט.first
יוצר גרסאות build רק לארכיטקטורה הראשונה (32 ביט במכשירים של 32 ביט ו-64 ביט במכשירים של 64 ביט).
כברירת מחדל, הערך של LOCAL_MULTILIB
לא מוגדר, ומערכת ה-build מחליטה איזו ארכיטקטורה לפתח על סמך סוג המודול ומשתני LOCAL_*
אחרים, כמו LOCAL_MODULE_TARGET_ARCH
ו-LOCAL_32_BIT_ONLY
.
אם רוצים לפתח את המודול לארכיטקטורות ספציפיות, צריך להשתמש במשתנים הבאים:
LOCAL_MODULE_TARGET_ARCH
– מגדירים את המשתנה הזה לרשימה של ארכיטקטורות, למשלarm x86 arm64
. אם הארכיטקטורה שנוצרת נמצאת ברשימה הזו, המערכת לכלול את המודול הנוכחי.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
– המשתנה הזה הוא ההיפך מ-LOCAL_MODULE_TARGET_ARCH
. אם הארכיטקטורה שנוצרת היאnot
ברשימה הזו, המערכת תיצור את המודול הנוכחי.
יש וריאציות קלות לשני המשתנים האלה:
LOCAL_MODULE_TARGET_ARCH_WARN
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
מערכת ה-build תזהיר אם המודול הנוכחי ידלג בגלל הארכיטקטורות שמפורטות.
כדי להגדיר דגלי build לארכיטקטורה מסוימת, משתמשים במשתני LOCAL_*
ספציפיים לארכיטקטורה, כאשר *
הוא סיומת ספציפית לארכיטקטורה. לדוגמה:
LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,
המשתנים האלה חלים רק אם מתבצע פיתוח של קובץ בינארי לארכיטקטורה הזו.
לפעמים קל יותר להגדיר דגלים על סמך העובדה שהקובץ הבינארי נוצר ל-32 ביט או ל-64 ביט. משתמשים במשתנה LOCAL_*
עם סיומת _32
או _64
, לדוגמה:
LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,
הגדרת נתיב ההתקנה של הספרייה
לגרסה ללא multilib, אפשר להשתמש ב-LOCAL_MODULE_PATH
כדי להתקין ספרייה במיקום אחר מלבד מיקום ברירת המחדל. לדוגמה, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
.
עם זאת, ב-build של multilib, צריך להשתמש ב-LOCAL_MODULE_RELATIVE_PATH
במקום:
LOCAL_MODULE_RELATIVE_PATH := hw
בפורמט הזה, גם הספריות של 64 ביט וגם הספריות של 32 ביט מותקנות במיקום הנכון.
אם אתם יוצרים קובץ הפעלה גם ב-32 ביט וגם ב-64 ביט, תוכלו להשתמש באחד מהמשתנים הבאים כדי להבדיל בין נתיב ההתקנה:
LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64
– מציין את שם הקובץ שמותקן.LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
– מציין את נתיב ההתקנה.
אחזור של ספרייה ביניים לקובצי המקור
ב-build של multilib, אם יוצרים קובצי מקור ל-$(local-intermediates-dir)
(או ל-$(intermediates-dir-for)
עם משתנים מפורשים), המערכת לא פועלת בצורה מהימנה. הסיבה לכך היא שהמקורות שנוצרו בשלב הביניים נדרשים גם ל-build של 32 סיביות וגם ל-build של 64 סיביות, אבל $(local-intermediates-dir)
מפנה רק לאחד משני הספריות הבינוניות.
מערכת ה-build מספקת ספרייה ביניים ייעודית שתומכת ב-multilib ליצירת מקורות. כדי לאחזר את הנתיב של הספרייה הביניים, משתמשים במאקרו $(local-generated-sources-dir)
או $(generated-sources-dir-for)
. השימושים במאקרואים האלה דומים ל-$(local-intermediates-dir)
ול-$(intermediates-dir-for)
.
אם קובץ מקור נוצר בתיקייה הייעודית הזו ונאסף על ידי LOCAL_GENERATED_SOURCES
, הוא נוצר גם ל-32 ביט וגם ל-64 ביט ב-build של multilib.
ציון ארכיטקטורת המערכת של יעדים בינאריים מוכנים מראש
ב-build של multilib, אי אפשר להשתמש ב-TARGET_ARCH
או ב-TARGET_ARCH
בשילוב עם TARGET_2ND_ARCH
כדי לציין את ארכיטקטורת המערכת של יעדי הבינארי שנוצרו מראש. במקום זאת, צריך להשתמש במשתני LOCAL_*
LOCAL_MODULE_TARGET_ARCH
או LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
בעזרת המשתנים האלה, מערכת ה-build יכולה לבחור את קובץ ה-binary המבוסס מראש של 32 ביט התואם, גם אם היא פועלת על build של multilib ב-64 ביט.
כדי להשתמש בארכיטקטורה שנבחרה כדי לחשב את נתיב המקור של הקובץ הבינארי שנוצר מראש, צריך להפעיל את הפונקציה $(get-prebuilt-src-arch)
.
מוודאים שייווצרו קובצי ODEX ב-32 סיביות וב-64 סיביות
במכשירים של 64 ביט, Google יוצרת כברירת מחדל קובצי ODEX של 32 ביט ושל 64 ביט לתמונת האתחול ולספריות Java. כברירת מחדל, Google יוצרת קובצי ODEX רק לארכיטקטורה הראשית של 64 סיביות בחבילות APK. אם אפליקציה מופעלת גם בתהליכים של 32 ביט וגם בתהליכים של 64 ביט, צריך להשתמש ב-LOCAL_MULTILIB := both
כדי לוודא שנוצרים גם קובצי ODEX של 32 ביט וגם קובצי ODEX של 64 ביט. אם יש באפליקציה ספריות JNI של 32 ביט או 64 ביט, הדגל הזה גם מורה למערכת ה-build לכלול אותן.