לפני שחרורו של אנדרואיד 7.0, אנדרואיד השתמשה ב-GNU Make באופן בלעדי כדי לתאר ולבצע את כללי הבנייה שלה. מערכת ה-Make build זוכה לתמיכה נרחבת ולשימוש נרחב, אך בקנה מידה של אנדרואיד הפכה לאטית, מועדת לשגיאות, בלתי ניתנת להרחבה וקשה לבדיקה. מערכת ה-Soong build מספקת את הגמישות הנדרשת עבור בניית אנדרואיד.
מסיבה זו, מפתחי פלטפורמות צפויים לעבור מ-Make ולאמץ את Soong בהקדם האפשרי. שלח שאלות לקבוצת Google המבוססת על אנדרואיד כדי לקבל תמיכה.
מה זה סונג?
מערכת הבנייה Soong הוצגה באנדרואיד 7.0 (Nougat) כדי להחליף את Make. הוא ממנף את כלי השיבוט Kati GNU Make ואת רכיב מערכת בניית Ninja כדי להאיץ את הבנייה של אנדרואיד.
עיין בתיאור מערכת ה-Android Make Build בפרויקט הקוד הפתוח של Android (AOSP) לקבלת הנחיות כלליות ושינויי מערכת עבור כותבי Android.mk כדי ללמוד על השינויים הדרושים להתאמה מ-Make to Soong.
ראה את הערכים הקשורים ל-build במילון המונחים להגדרות של מונחי מפתח ואת קובצי ההפניה של Soong לפרטים מלאים.
השוואת בצע וסונג
להלן השוואה של תצורת עשה עם Soong משיג את אותו הדבר בקובץ תצורת Soong (Blueprint או .bp
).
תעשה דוגמה
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libxmlrpc++
LOCAL_MODULE_HOST_OS := linux
LOCAL_RTTI_FLAG := -frtti
LOCAL_CPPFLAGS := -Wall -Werror -fexceptions
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/src
LOCAL_SRC_FILES := $(call \
all-cpp-files-under,src)
include $(BUILD_SHARED_LIBRARY)
דוגמה קצרה
cc_library_shared {
name: “libxmlrpc++”,
rtti: true,
cppflags: [
“-Wall”,
“-Werror”,
“-fexceptions”,
],
export_include_dirs: [“src”],
srcs: [“src/**/*.cpp”],
target: {
darwin: {
enabled: false,
},
},
}
ראה תצורת בנייה פשוטה לדוגמאות תצורת Soong ספציפיות לבדיקה.
פורמט קובץ Android.bp
לפי התכנון, קבצי Android.bp
הם פשוטים. הם אינם מכילים הצהרות תנאים או זרימת בקרה; כל המורכבות מטופלת על ידי לוגיקה לבנות שנכתבה ב-Go. במידת האפשר, התחביר והסמנטיקה של קבצי Android.bp
דומים לקבצי Bazel BUILD .
מודולים
מודול בקובץ Android.bp
מתחיל עם סוג מודול ואחריו קבוצה של מאפיינים בשם name: "value",
פורמט:
cc_binary {
name: "gzip",
srcs: ["src/test/minigzip.c"],
shared_libs: ["libz"],
stl: "none",
}
לכל מודול חייב להיות מאפיין name
, והערך חייב להיות ייחודי בכל קבצי Android.bp
, למעט ערכי מאפיין name
במרחבי שמות ובמודולים שנבנו מראש, שעלולים לחזור על עצמם.
המאפיין srcs
מציין את קובצי המקור המשמשים לבניית המודול, כרשימה של מחרוזות. אתה יכול להפנות לפלט של מודולים אחרים שמייצרים קבצי מקור, כמו genrule
או filegroup
, על ידי שימוש בתחביר ההפניה של המודול ":<module-name>"
.
לרשימה של סוגי מודולים חוקיים והמאפיינים שלהם, עיין ב- Soong Modules Reference .
סוגים
משתנים ומאפיינים מוקלדים היטב, כאשר משתנים מבוססים באופן דינמי על ההקצאה הראשונה, ומאפיינים מוגדרים באופן סטטי על ידי סוג המודול. הסוגים הנתמכים הם:
- בוליאניות (
true
אוfalse
) - מספרים שלמים (
int
) - מחרוזות (
"string"
) - רשימות של מחרוזות (
["string1", "string2"]
) - מפות (
{key1: "value1", key2: ["value2"]}
)
מפות עשויות להכיל ערכים מכל סוג, כולל מפות מקוננות. לרשימות ומפות עשויות להיות פסיקים עוקבים אחרי הערך האחרון.
גלובס
מאפיינים שלוקחים רשימה של קבצים, כגון srcs
, יכולים גם לקבל דפוסי גלוב. תבניות גלוב יכולות להכיל את התו הכללי הרגיל של UNIX *
, למשל *.java
. תבניות גלוב יכולות להכיל גם תו כללי **
בודד כרכיב נתיב, התואם לאפס רכיבי נתיב או יותר. לדוגמה, java/**/*.java
מתאים הן לתבניות java/Main.java
והן לתבניות java/com/android/Main.java
.
משתנים
קובץ Android.bp
עשוי להכיל הקצאות משתנים ברמה העליונה:
gzip_srcs = ["src/test/minigzip.c"],
cc_binary {
name: "gzip",
srcs: gzip_srcs,
shared_libs: ["libz"],
stl: "none",
}
היקף המשתנים הוא לשאר הקובץ שבו הם מוצהרים, כמו גם לכל קבצי צאצא של Blueprint. משתנים הם בלתי ניתנים לשינוי למעט חריג אחד: ניתן לצרף אותם עם הקצאת +=
, אבל רק לפני שהפניה אליהם.
הערות
קבצי Android.bp
יכולים //
הערות /* */
ת בסגנון רב-קו.
מפעילים
ניתן להוסיף מחרוזות, רשימות של מחרוזות ומפות באמצעות האופרטור +. ניתן לסכם מספרים שלמים באמצעות האופרטור +
. הוספת מפה מייצרת את איחוד המפתחות בשתי המפות, תוך הוספת הערכים של כל המפתחות הקיימים בשתי המפות.
תנאים
Soong אינו תומך בתנאים בקבצי Android.bp
. במקום זאת, המורכבות בכללי בנייה שתדרוש תנאים מטופלים ב-Go, שם ניתן להשתמש בתכונות שפה ברמה גבוהה, וניתן לעקוב אחר תלות מרומזת שהוכנסה על ידי תנאים. רוב התניות מומרות למאפיין מפה, כאשר אחד מהערכים במפה נבחר ומצורף למאפיינים ברמה העליונה.
לדוגמה, כדי לתמוך בקבצים ספציפיים לארכיטקטורה:
cc_library {
...
srcs: ["generic.cpp"],
arch: {
arm: {
srcs: ["arm.cpp"],
},
x86: {
srcs: ["x86.cpp"],
},
},
}
מעצב
Soong כולל פורמט קנוני לקובצי Blueprint, בדומה ל- gofmt . כדי לאתחל מחדש באופן רקורסיבי את כל קבצי Android.bp
בספרייה הנוכחית, הרץ:
bpfmt -w .
הפורמט הקנוני כולל כניסות של ארבע רווחים, שורות חדשות אחרי כל רכיב של רשימה מרובה אלמנטים ופסיק נגרר ברשימות ובמפות.
מודולים מיוחדים
לכמה קבוצות מודול מיוחדות יש מאפיינים ייחודיים.
ברירת המחדל של מודולים
ניתן להשתמש במודול ברירת מחדל כדי לחזור על אותם מאפיינים במספר מודולים. לדוגמה:
cc_defaults {
name: "gzip_defaults",
shared_libs: ["libz"],
stl: "none",
}
cc_binary {
name: "gzip",
defaults: ["gzip_defaults"],
srcs: ["src/test/minigzip.c"],
}
מודולים מובנים מראש
חלק מסוגי המודולים שנבנו מראש מאפשרים למודול לקבל את אותו שם כמו עמיתיו מבוססי המקור. לדוגמה, יכול להיות cc_prebuilt_binary
בשם foo
כאשר יש כבר cc_binary
באותו שם. זה נותן למפתחים את הגמישות לבחור איזו גרסה לכלול במוצר הסופי שלהם. אם תצורת build מכילה את שתי הגרסאות, ערך הדגל prefer
בהגדרת המודול המובנה מראש מכתיב לאיזו גרסה יש עדיפות. שים לב שלחלק מהמודולים המובנים מראש יש שמות שאינם מתחילים ב- prebuilt
, כגון android_app_import
.
מודולי מרחב שמות
עד להמרה מלאה של Android מ-Make ל-Soong, תצורת המוצר של Make חייבת לציין ערך PRODUCT_SOONG_NAMESPACES
. הערך שלו צריך להיות רשימה מופרדת ברווחים של מרחבי שמות ש-Soong מייצאת ל-Make כדי להיבנות על ידי הפקודה m
. לאחר השלמת ההמרה של אנדרואיד ל-Soong, הפרטים של הפעלת מרחבי שמות עשויים להשתנות.
Soong מספקת את היכולת למודולים בספריות שונות לציין את אותו שם, כל עוד כל מודול מוצהר בתוך מרחב שמות נפרד. ניתן להכריז על מרחב שמות כך:
soong_namespace {
imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}
שים לב שלמרחב שמות אין מאפיין שם; הנתיב שלו מוקצה אוטומטית כשמו.
לכל מודול Soong מוקצה מרחב שמות על סמך מיקומו בעץ. כל מודול Soong נחשב למרחב השמות המוגדר על ידי soong_namespace
שנמצא בקובץ Android.bp
בספרייה הנוכחית או בספריית האב הקדמונית הקרובה ביותר. אם לא נמצא מודול soong_namespace
כזה, המודול נחשב למרחב השמות המרומז.
הנה דוגמה: Soong מנסה לפתור תלות D שהוכרזה על ידי מודול M במרחב השמות N שמייבא מרחבי שמות I1, I2, I3...
- לאחר מכן אם D הוא שם מלא של הצורה
//namespace:module
, רק מרחב השמות שצוין יחפש את שם המודול שצוין. - אחרת, Soong מחפש תחילה מודול בשם D המוצהר במרחב השמות N.
- אם המודול הזה לא קיים, Soong מחפש מודול בשם D במרחבי השמות I1, I2, I3...
- לבסוף, סונג מסתכל במרחב השמות של השורש.