מערכת ה-build תומכת ב-build של קבצים בינאריים לשתי ארכיטקטורות CPU יעד, 32 ביט ו-64 ביט, באותו build. הגרסה הזו עם שתי מטרות נקראת גרסת multilib.
עבור ספריות סטטיות וספריות משותפות מובנות, מערכת ה-build מגדירה כללים ליצירת קבצים בינאריים לשתי הארכיטקטורות. הגדרת המוצר (PRODUCT_PACKAGES
), יחד עם גרף יחסי התלות, קובעת אילו קבצים בינאריים נוצרים ומוגדרים בתמונת המערכת.
במקרה של קובצי הפעלה ואפליקציות, מערכת ה-build יוצרת כברירת מחדל רק את גרסת 64 ביט, אבל אפשר לשנות את ההגדרה הזו באמצעות משתנה גלובלי BoardConfig.mk
או משתנה בהיקף מודול.
זיהוי ארכיטקטורת CPU ו-ABI שנייה
BoardConfig.mk
כולל את המשתנים הבאים להגדרת ארכיטקטורת ה-CPU השנייה וממשק ה-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
.
ב-multilib build, שמות המודולים ב-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
יוצר גרסאות של 32 ביט ו-64 ביט. -
32
builds only 32 bit. -
64
builds only 64 bit. -
first
builds רק לארכיטקטורה הראשונה (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
.
אבל ב-multilib build, צריך להשתמש ב-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
- מציין את נתיב ההתקנה.
קבלת ספריית ביניים לקובצי מקור
ב-multilib build, אם יוצרים קובצי מקור ל-$(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 ביט בגרסה מרובת ספריות.
ציון ארכיטקטורת המערכת של יעדים בינאריים מוכנים מראש
ב-multilib build, אי אפשר להשתמש ב-TARGET_ARCH
או ב-TARGET_ARCH
בשילוב עם TARGET_2ND_ARCH
כדי לציין את ארכיטקטורת המערכת של יעדי הקבצים הבינאריים שנוצרו מראש. במקום זאת, משתמשים במשתנים LOCAL_*
, LOCAL_MODULE_TARGET_ARCH
או LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
בעזרת המשתנים האלה, מערכת ה-build יכולה לבחור את הקובץ הבינארי המקביל שנוצר מראש ב-32 ביט, גם אם היא פועלת על build של multilib ב-64 ביט.
אם רוצים להשתמש בארכיטקטורה שנבחרה כדי לחשב את נתיב המקור של הקובץ הבינארי שנבנה מראש, קוראים ל-$(get-prebuilt-src-arch)
.
מוודאים שנוצר קובץ ODEX ב-32 ביט וב-64 ביט
במכשירי 64 ביט, כברירת מחדל, Google יוצרת קובצי ODEX של 32 ביט ו-64 ביט לתמונת האתחול ולכל ספריות Java. במקרה של קובצי APK, כברירת מחדל Google יוצרת קובץ ODEX רק לארכיטקטורה הראשית של 64 ביט. אם אפליקציה מופעלת בתהליכים של 32 ביט וגם של 64 ביט, צריך להשתמש ב-LOCAL_MULTILIB := both
כדי לוודא שנוצרים קובצי ODEX של 32 ביט וגם של 64 ביט. אם האפליקציה כוללת ספריות JNI של 32 ביט או 64 ביט, הדגל הזה גם מציין למערכת הבנייה לכלול אותן.