קבצי Android.bp
פשוטים מאוד. הם לא מכילים הצהרות מותנות או הצהרות של זרימת בקרה. כל המורכבות מטופלת על ידי לוגיקת בנייה שנכתבה ב-Go.
מודולים
מודול בקובץ 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"]}
)
מפות יכולות להכיל ערכים מכל סוג, כולל מפות במבנה היררכי. יכול להיות שיהיו פסיקים מיותרים אחרי הערך האחרון ברשימות ובמפות.
Globs
מאפיינים שמקבלים רשימה של קבצים, כמו srcs
, יכולים לקבל גם תבניות glob. תבניות Glob יכולות להכיל את התו הכללי הרגיל של UNIX *
, לדוגמה *.java
. תבניות Glob יכולות להכיל גם תו **
wildcard יחיד כרכיב נתיב, שתואם לאפס או יותר רכיבי נתיב. לדוגמה, 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
יכולים להכיל הערות /* */
מרובות שורות בסגנון C והערות //
של שורה אחת בסגנון C++.
מפעילים
אפשר להוסיף מחרוזות, רשימות של מחרוזות ומפות באמצעות האופרטור +.
אפשר לחשב סכום של מספרים שלמים באמצעות האופרטור +
. כשמוסיפים מפה, מתקבל איחוד של המפתחות בשתי המפות, והערכים של כל המפתחות שמופיעים בשתי המפות מתווספים.
מודולים של ברירות מחדל
מפתחים יכולים להשתמש במודול ברירת מחדל כדי לחזור על אותם מאפיינים בכמה מודולים. לדוגמה:
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, צריך לציין ערך PRODUCT_SOONG_NAMESPACES
בהגדרת המוצר של Make. הערך שלו צריך להיות רשימה של מרחבי שמות שמופרדים ברווחים, ש-Soong מייצא ל-Make כדי לבנות אותם באמצעות הפקודה m
. אחרי שההמרה של Android ל-Soong תושלם, יכול להיות שפרטי ההפעלה של מרחבי השמות ישתנו.
מערכת Soong מאפשרת למודולים בספריות שונות לציין את אותו שם, כל עוד כל מודול מוצהר במרחב שמות נפרד. מפתחים יכולים להצהיר על מרחב שמות:
soong_namespace {
imports: ["path/to/otherNamespace1", "path/to/otherNamespace2"],
}
שימו לב שלמרחב שמות אין מאפיין name
, והנתיב שלו מוקצה אוטומטית כשם שלו.
לכל מודול Soong מוקצה מרחב שמות על סמך המיקום שלו בעץ.
כל מודול Soong נחשב כחלק ממרחב השמות שמוגדר על ידי soong_namespace
שנמצא בקובץ Android.bp
בספרייה הנוכחית או בספריית האב הקרובה ביותר. אם לא נמצא מודול soong_namespace
כזה, המודול נחשב כמודול במרחב השמות הבסיסי המרומז.
לדוגמה: סונג מנסה לפתור את התלות D שהוגדרה על ידי המודול M במרחב השמות N שמייבא את מרחבי השמות I1, I2, I3…
- אם D הוא שם מלא מהצורה
//namespace:module
, החיפוש של שם המודול שצוין יתבצע רק במרחב השמות שצוין. - אחרת, Soong מחפש קודם מודול בשם D שהוגדר במרחב השמות N.
- אם המודול הזה לא קיים, Soong מחפש מודול בשם D במרחבי השמות I1, I2, I3…
- מערכת Soong מחפשת במרחב השמות הבסיסי.
משפטי תנאי
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 .
הפורמט הקנוני כולל הזחות של ארבעה רווחים, שורות חדשות אחרי כל רכיב ברשימה מרובת רכיבים ופסיק בסוף רשימות ומפות.