אפשר להשתמש במידע בדף הזה כדי ליצור את קובצי ה-makefile למכשיר ולמוצר.
לכל מודול חדש של Android צריך להיות קובץ תצורה כדי להנחות את מערכת ה-build לגבי המטא-נתונים של המודול, יחסי התלות בזמן הידור והוראות האריזה. ב-Android נעשה שימוש במערכת ה-build של Soong. מידע נוסף על מערכת ה-build של Android זמין במאמר יצירת Android.
הסבר על שכבות build
היררכיית ה-build כוללת את שכבות ההפשטה שתואמות למבנה הפיזי של המכשיר. השכבות האלה מתוארות בטבלה הבאה. כל שכבה קשורה לשכבה שמעליה בקשר מסוג 'אחד לרבים'. לדוגמה, לארכיטקטורה יכולה להיות יותר מלוח אחד, וכל לוח יכול לכלול יותר ממוצר אחד. אפשר להגדיר אלמנט בשכבה מסוימת כמיקוד של אלמנט באותה שכבה, וכך למנוע העתקה ולפשט את התחזוקה.
שכבה | דוגמה | תיאור |
---|---|---|
מוצר | myProduct, myProduct_eu, myProduct_eu_fr, j2, sdk | בשכבת המוצר מוגדר מפרט התכונות של המוצר ששולחים, כמו המודולים ליצירה, הלוקאלים הנתמכים וההגדרות של לוקאלים שונים. במילים אחרות, זהו השם של המוצר הכולל. משתנים ספציפיים למוצר מוגדרים בקובצי makefile של הגדרת המוצר. מוצר יכול לרשת הגדרות של מוצרים אחרים, וכך לפשט את התחזוקה. שיטה נפוצה היא ליצור מוצר בסיס שמכיל תכונות שחלות על כל המוצרים, ואז ליצור וריאציות של המוצר על סמך מוצר הבסיס. לדוגמה, שני מוצרים שונים רק ברדיו שלהם (CDMA לעומת GSM) יכולים לרשת מאותו מוצר בסיס שלא מוגדר בו רדיו. |
לוח/מכשיר | מקרל, כחול-קו, קורל | השכבה של הלוח או המכשיר מייצגת את השכבה הפיזית של הפלסטיק במכשיר (כלומר, העיצוב התעשייתי של המכשיר). השכבה הזו מייצגת גם את הסכימה הבסיסית של המוצר. אלה כוללים את הציוד ההיקפי על הלוח ואת ההגדרות שלו. השמות משמשים רק כקודים להגדרות שונות של הלוח או המכשיר. |
קשת | arm, x86, arm64, x86_64 | בשכבת הארכיטקטורה מתוארת הגדרת המעבד והממשק הבינארי של האפליקציה (ABI) שפועל בלוח. |
שימוש בוריאנטים של build
כשמפתחים גרסה למוצר מסוים, כדאי ליצור וריאציות קלות בגרסה הסופית של המוצר. בהגדרת המודול, אפשר לציין תגים עם LOCAL_MODULE_TAGS
, שיכול להיות ערך אחד או יותר מ-optional
(ברירת המחדל), debug
ו-eng
.
אם לא צוין תג למודול (באמצעות LOCAL_MODULE_TAGS
), הערך שמוגדר כברירת מחדל לתג הוא optional
. מודול אופציונלי מותקן רק אם הוא נדרש בהגדרת המוצר באמצעות PRODUCT_PACKAGES
.
אלה וריאציות ה-build שמוגדרות כרגע.
וריאנט | תיאור |
---|---|
eng
|
זהו הטעם שמוגדר כברירת מחדל.
|
user
|
הווריאנט שמיועד להיות הביטים הסופיים של הגרסה.
|
userdebug
|
כמו user , למעט החריגים הבאים:
|
הנחיות ל-userdebug
הפעלת גרסאות build של userdebug בבדיקה עוזרת למפתחי המכשירים להבין את הביצועים והעוצמה של גרסאות שעדיין נמצאות בפיתוח. כדי לשמור על עקביות בין גרסאות build לשימוש משתמשים לבין גרסאות build לשימוש למטרות ניפוי באגים, וכדי לקבל מדדים מהימנים בגרסאות build שמשמשות לניפוי באגים, מפתחי המכשירים צריכים לפעול לפי ההנחיות הבאות:
- userdebug מוגדר כגרסת build של משתמש עם הרשאת root מופעלת, למעט:
- אפליקציות userdebug בלבד שפועלות רק על פי דרישה של המשתמש
- פעולות שפועלות רק במהלך תחזוקה במצב חוסר פעילות (במטען/טעינה מלאה), למשל שימוש ב-
dex2oatd
במקום ב-dex2oat
לצורך הידור ברקע
- אין לכלול תכונות שמופעלות או מושבתות כברירת מחדל בהתאם לסוג ה-build. מומלץ למפתחים לא להשתמש בכל סוג של רישום ביומן שמשפיע על חיי הסוללה, כמו רישום ביומן לניפוי באגים או דמפ של אשכול.
- צריך להגדיר בבירור את כל תכונות ניפוי הבאגים שמופעלות כברירת מחדל ב-userdebug, ולשתף אותן עם כל המפתחים שעובדים על הפרויקט. מומלץ להפעיל את תכונות ניפוי הבאגים רק לזמן מוגבל, עד שהבעיה שאתם מנסים לנפות תיפתר.
התאמה אישית של ה-build באמצעות שכבות-על של משאבים
מערכת ה-build של Android משתמשת בשכבות-על של משאבים כדי להתאים אישית מוצר בזמן ה-build. שכבות-על של משאבים מציינות קובצי משאבים שחלים מעל הגדרות ברירת המחדל. כדי להשתמש בשכבות-על של משאבים, משנים את קובץ ה-build של הפרויקט כך ש-PRODUCT_PACKAGE_OVERLAYS
יהיה נתיב ביחס לספרייה ברמה העליונה. הנתיב הזה הופך לשורש צל שמערכת ה-build מחפשת בו משאבים יחד עם השורש הנוכחי.
ההגדרות הנפוצות ביותר בהתאמה אישית נמצאות בקובץ frameworks/base/core/res/res/values/config.xml.
כדי להגדיר שכבת-על של משאבים בקובץ הזה, מוסיפים את ספריית שכבת-העל לקובץ ה-build של הפרויקט באמצעות אחת מהשיטות הבאות:
PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
או
PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
לאחר מכן מוסיפים קובץ שכבת-על לספרייה, לדוגמה:
vendor/foobar/overlay/frameworks/base/core/res/res/values/config.xml
מחרוזות או מערכי מחרוזות שנמצאים בקובץ שכבת-העל config.xml
מחליפים את אלה שנמצאים בקובץ המקורי.
פיתוח מוצר
יש הרבה דרכים לארגן את קובצי המקור של המכשיר. בהמשך מופיעה תיאור קצר של אחת מהדרכים לארגון הטמעת Pixel.
Pixel מיושם עם הגדרת מכשיר ראשית בשם marlin
. מתצורת המכשיר הזו נוצר מוצר באמצעות קובץ makefile להגדרת המוצר, שמצהיר על מידע ספציפי למוצר לגבי המכשיר, כמו השם והדגם. אפשר לעיין בספרייה device/google/marlin
כדי לראות איך כל זה מוגדר.
כתיבת קובצי makefile של מוצרים
בשלבים הבאים מוסבר איך להגדיר קובצי make של מוצרים באופן דומה לזה של קו מוצרי Pixel:
- יוצרים ספרייה
device/<company-name>/<device-name>
למוצר. לדוגמה,device/google/marlin
. הספרייה הזו תכיל את קוד המקור של המכשיר ואת קובצי ה-makefile ליצירת ה-build. - יוצרים קובץ makefile
device.mk
שמצהיר על הקבצים והמודולים הנדרשים למכשיר. דוגמה מופיעה בקטעdevice/google/marlin/device-marlin.mk
. - יוצרים קובץ makefile להגדרת המוצר כדי ליצור מוצר ספציפי על סמך המכשיר. קובץ ה-makefile הבא לקוח מ-
device/google/marlin/aosp_marlin.mk
לדוגמה. שימו לב שהמוצר עובר בירושה מהקבציםdevice/google/marlin/device-marlin.mk
ו-vendor/google/marlin/device-vendor-marlin.mk
דרך קובץ ה-makefile, וגם מכריז על המידע הספציפי למוצר, כמו שם, מותג ודגם.# Inherit from the common Open Source product configuration $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk) $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk) PRODUCT_NAME := aosp_marlin PRODUCT_DEVICE := marlin PRODUCT_BRAND := Android PRODUCT_MODEL := AOSP on msm8996 PRODUCT_MANUFACTURER := Google PRODUCT_RESTRICT_VENDOR_FILES := true PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin $(call inherit-product, device/google/marlin/device-marlin.mk) $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk) PRODUCT_PACKAGES += \ Launcher3QuickStep \ WallpaperPicker
במאמר הגדרת משתני הגדרת המוצר מפורטים משתנים נוספים ספציפיים למוצר שאפשר להוסיף לקובצי ה-make.
- יוצרים קובץ
AndroidProducts.mk
שמצביע על קובצי ה-makefile של המוצר. בדוגמה הזו, נדרש רק קובץ ה-makefile של הגדרת המוצר. הדוגמה הבאה היא מ-device/google/marlin/AndroidProducts.mk
(שמכיל גם את marlin, Pixel, וגם את sailfish, Pixel XL, שחלקו את רוב ההגדרות):PRODUCT_MAKEFILES := \ $(LOCAL_DIR)/aosp_marlin.mk \ $(LOCAL_DIR)/aosp_sailfish.mk COMMON_LUNCH_CHOICES := \ aosp_marlin-userdebug \ aosp_sailfish-userdebug
- יוצרים קובץ makefile
BoardConfig.mk
שמכיל הגדרות ספציפיות ללוח. דוגמה מופיעה בקטעdevice/google/marlin/BoardConfig.mk
. - ב-Android מגרסה 9 ומטה בלבד, יוצרים קובץ
vendorsetup.sh
כדי להוסיף את המוצר ('ארוחת צהריים משולבת') לגרסה המאוחדת, יחד עם גרסה של הגרסה המאוחדת, ומופרדים ביניהם באמצעות מקף. לדוגמה:add_lunch_combo <product-name>-userdebug
- בשלב הזה, אפשר ליצור עוד וריאנטים של מוצרים על סמך אותו מכשיר.
הגדרת משתנים של הגדרת המוצר
משתנים ספציפיים למוצר מוגדרים בקובץ ה-makefile של המוצר. בטבלה מוצגים חלק מהמשתנים שמתוחזקים בקובץ הגדרת המוצר.
משתנה | תיאור | דוגמה |
---|---|---|
PRODUCT_AAPT_CONFIG
|
הגדרות aapt לשימוש ביצירת חבילות.
|
|
PRODUCT_BRAND
|
המותג (למשל, ספק) שהתוכנה מותאמת אישית עבורו. | |
PRODUCT_CHARACTERISTICS
|
מאפייני aapt כדי לאפשר הוספה של משאבים ספציפיים לווריאציה לחבילה.
|
tablet , nosdcard
|
PRODUCT_COPY_FILES
|
רשימה של מילים כמו source_path:destination_path . צריך להעתיק את הקובץ בנתיב המקור לנתיב היעד כשמפתחים את המוצר הזה. הכללים של שלבי ההעתקה מוגדרים ב-config/makefile .
|
|
PRODUCT_DEVICE
|
השם של העיצוב התעשייתי. זהו גם שם הלוח, ומערכת ה-build משתמשת בו כדי לאתר את BoardConfig.mk .
|
tuna
|
PRODUCT_LOCALES
|
רשימה מופרדת בפסיקים של זוגות של קוד שפה בן שתי אותיות וקוד מדינה בן שתי אותיות שמתארים כמה הגדרות של המשתמש, כמו שפת ממשק המשתמש, הזמן, התאריך וסימון המטבע. הלוקאל הראשון שמופיע ב-PRODUCT_LOCALES משמש כלוקאל ברירת המחדל של המוצר.
|
en_GB , de_DE , es_ES , fr_CA
|
PRODUCT_MANUFACTURER
|
שם היצרן. |
acme
|
PRODUCT_MODEL
|
השם של המוצר הסופי שגלוי למשתמש הקצה. | |
PRODUCT_NAME
|
השם של המוצר הכולל שגלוי למשתמשי הקצה. מופיע במסך הגדרות > מידע כללי. | |
PRODUCT_OTA_PUBLIC_KEYS
|
רשימת מפתחות ציבוריים של המוצר לשידור אוויר (OTA). | |
PRODUCT_PACKAGES
|
רשימת קובצי ה-APK והמודולים להתקנה. | אנשי קשר ביומן |
PRODUCT_PACKAGE_OVERLAYS
|
מציין אם להשתמש במשאבים שמוגדרים כברירת מחדל או להוסיף שכבות-על ספציפיות למוצר. |
vendor/acme/overlay
|
PRODUCT_SYSTEM_PROPERTIES
|
רשימה של הקצאות של מאפייני המערכת בפורמט "key=value" למחיצה של המערכת. אפשר להגדיר מאפייני מערכת למחיצות אחרות באמצעות PRODUCT_<PARTITION>_PROPERTIES , כמו ב-PRODUCT_VENDOR_PROPERTIES למחיצה של הספק. שמות המחיצות הנתמכים: SYSTEM , VENDOR , ODM , SYSTEM_EXT ו-PRODUCT .
|
הגדרת שפת ברירת המחדל של המערכת ומסנן של אזור גיאוגרפי
אפשר להשתמש במידע הזה כדי להגדיר את שפת ברירת המחדל ואת מסנן האזור של המערכת, ואז להפעיל את מסנן האזור לסוג מכשיר חדש.
מאפיינים
מגדירים את שפת ברירת המחדל ואת מסנן הלוקאל של המערכת באמצעות מאפייני מערכת ייעודיים:
ro.product.locale
: להגדרת לוקאל ברירת המחדל. הערך הזה מוגדר בהתחלה ללוקאל הראשון במשתנהPRODUCT_LOCALES
. אפשר לשנות את הערך הזה. (מידע נוסף זמין בטבלה הגדרת משתני הגדרת המוצר).ro.localization.locale_filter
: להגדרת מסנן אזור גיאוגרפי, באמצעות ביטוי רגולרי שחלים על שמות של אזורים גיאוגרפיים. לדוגמה:- מסנן כולל:
^(de-AT|de-DE|en|uk).*
– מאפשר רק גרמנית (הגרסאות של אוסטריה וגרמניה), את כל הגרסאות של אנגלית ואוקראינית - מסנן בלעדי:
^(?!de-IT|es).*
– לא כולל גרמנית (גרסה לאיטליה) וכל הגרסאות של הספרדית.
- מסנן כולל:
הפעלת המסנן של אזור הזמן
כדי להפעיל את המסנן, מגדירים את ערך המחרוזת של מאפיין המערכת ro.localization.locale_filter
.
הגדרת ערך מאפיין הסינון ושפת ברירת המחדל באמצעות oem/oem.prop
במהלך כיול המפעל מאפשרת להגדיר הגבלות בלי להטמיע את המסנן בתמונת המערכת.
כדי לוודא שהמאפיינים האלה ייאספו מהמחיצה של ה-OEM, מוסיפים אותם למשתנה PRODUCT_OEM_PROPERTIES
כפי שמתואר בהמשך:
# Delegation for OEM customization
PRODUCT_OEM_PROPERTIES += \
ro.product.locale \
ro.localization.locale_filter
לאחר מכן, הערכים בפועל נכתבים ב-oem/oem.prop
בסביבת הייצור כדי לשקף את דרישות היעד. בגישה הזו, ערכי ברירת המחדל נשמרים במהלך האיפוס להגדרות המקוריות, כך שההגדרות הראשוניות נראות למשתמש בדיוק כמו הגדרה ראשונית.
הגדרת ADB_VENDOR_KEYS כדי להתחבר דרך USB
משתנה הסביבה ADB_VENDOR_KEYS
מאפשר ליצרני המכשירים לגשת ל-builds שניתן לנפות באגים בהם (-userdebug ו--eng, אבל לא -user) דרך adb ללא הרשאה ידנית.
בדרך כלל, adb יוצר מפתח אימות RSA ייחודי לכל מחשב לקוח, ושולח אותו לכל מכשיר מחובר. זהו מפתח ה-RSA שמוצג בתיבת הדו-שיח של הרשאת adb. לחלופין, אפשר להטמיע מפתחות ידועים בתמונת המערכת ולשתף אותם עם לקוח adb.
האפשרות הזו שימושית לפיתוח מערכת הפעלה ובמיוחד לבדיקה, כי היא מונעת את הצורך לבצע אינטראקציה ידנית עם תיבת הדו-שיח של הרשאת adb.
כדי ליצור מפתחות של ספקים, אדם אחד (בדרך כלל מנהל גרסאות) צריך:
- יוצרים זוג מפתחות באמצעות
adb keygen
. במכשירי Google, Google יוצרת זוג מפתחות חדש לכל גרסה חדשה של מערכת ההפעלה. - בודקים את זוגות המפתחות במקום כלשהו בעץ המקור. Google שומרת אותם, לדוגמה, ב-
vendor/google/security/adb/
. - מגדירים את משתנה ה-build
PRODUCT_ADB_KEYS
כך שיצביע על ספריית המפתחות. Google עושה זאת על ידי הוספת קובץAndroid.mk
בספריית המפתחות עם הערךPRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub
, כדי לוודא שנזכור ליצור זוג מפתחות חדש לכל גרסה של מערכת ההפעלה.
זהו קובץ ה-makefile שבו Google משתמשת בספרייה שבה אנחנו מאחסנים את זוגות המפתחות שאנחנו שומרים בכל גרסה:
PRODUCT_ADB_KEYS := $(LOCAL_PATH)/$(PLATFORM_VERSION).adb_key.pub ifeq ($(wildcard $(PRODUCT_ADB_KEYS)),) $(warning ========================) $(warning The adb key for this release) $(warning ) $(warning $(PRODUCT_ADB_KEYS)) $(warning ) $(warning does not exist. Most likely PLATFORM_VERSION in build/core/version_defaults.mk) $(warning has changed and a new adb key needs to be generated.) $(warning ) $(warning Please run the following commands to create a new key:) $(warning ) $(warning make -j8 adb) $(warning LOGNAME=android-eng HOSTNAME=google.com adb keygen $(patsubst %.pub,%,$(PRODUCT_ADB_KEYS))) $(warning ) $(warning and upload/review/submit the changes) $(warning ========================) $(error done) endif
כדי להשתמש במפתחות של הספקים האלה, מהנדס צריך רק להגדיר את משתנה הסביבה ADB_VENDOR_KEYS
כך שיצביע על הספרייה שבה זוגות המפתחות מאוחסנים.
כך adb
ינסו קודם את המפתחות הקנוניים האלה, לפני שיחזרו למפתח המארח שנוצר שדורש הרשאה ידנית. אם adb
לא יכול להתחבר למכשיר לא מורשה, הודעת השגיאה תציע להגדיר את ADB_VENDOR_KEYS
אם הוא עדיין לא מוגדר.