מודולים של Rust ל-Android

כעיקרון כללי, rust_*הגדרות המודולים תואמות באופן הדוק לשימוש ולציפיות.cc_* הדוגמה הבאה היא של הגדרת מודול לקובץ בינארי של Rust:

rust_binary {
    name: "hello_rust",
    crate_name: "hello_rust",
    srcs: ["src/hello_rust.rs"],
    host_supported: true,
}

בדף הזה מפורטים הנכסים הנפוצים ביותר של מודולים של rust_*. מידע נוסף על סוגים ספציפיים של מודולים ודוגמאות להגדרות של מודולים זמין במאמרים מודולים בינאריים, מודולים של ספריות או מודולים של בדיקות.

סוגים בסיסיים של מודולים

סוגהגדרהלמידע נוסף
rust_binaryקובץ בינארי של Rust Binary Modules page
rust_libraryיוצר ספריית Rust ומספק את הווריאציות rlib ו-dylib. rust_library, בדף Library Modules (מודולים של ספרייה).
rust_ffiיוצר ספריית C של Rust שאפשר להשתמש בה במודולים של cc, ומספק גרסאות סטטיות ומשותפות. rust_ffi, דף המודולים של הספרייה
rust_proc_macroיוצר ספריית proc-macro Rust. (הם דומים לפלאגינים של קומפיילר). rust_proc_macro, דף המודולים של ספריות
rust_testיוצר קובץ בינארי של בדיקת Rust שמשתמש במערכת הבדיקה הסטנדרטית של Rust. הדף Test Modules
rust_fuzzנוצר קובץ בינארי של Rust fuzz באמצעות libfuzzer. דוגמה למודול rust_fuzz
rust_protobufיוצר קוד מקור ומפיק ספרייה של Rust שמספקת ממשק ל-protobuf מסוים. הדפים Protobufs Modules ו-Source Generators
rust_bindgenיוצר מקור ומפיק ספריית Rust שמכילה קשירות Rust לספריות C. הדפים Bindgen Bindings Modules ו-Source Generators

מאפיינים נפוצים חשובים

המאפיינים האלה משותפים לכל מודולי Rust של Android. נכסים נוספים (ייחודיים) שמשויכים למודולים ספציפיים של Rust מפורטים בדף של אותו מודול.

שם

name הוא השם של המודול. בדומה למודולים אחרים של Soong, השם צריך להיות ייחודי ברוב סוגי המודולים של Android.bp. כברירת מחדל, name משמש כשם קובץ הפלט. אם שם קובץ הפלט צריך להיות שונה משם המודול, צריך להשתמש במאפיין stem כדי להגדיר אותו.

גבעול

stem (אופציונלי) מאפשר שליטה ישירה בשם קובץ הפלט (לא כולל את סיומת הקובץ וסיומות אחרות). לדוגמה, rust_library_rlib ספרייה עם ערך בסיס של libfoo יוצרת קובץ libfoo.rlib. אם לא מציינים ערך למאפיין stem, שם קובץ הפלט יהיה שם המודול כברירת מחדל.

משתמשים בפונקציה stem כשאי אפשר להגדיר את שם המודול כשם הקובץ הרצוי של הפלט. לדוגמה, שם ה-rust_library של תיבת log הוא liblog_rust, כי כבר קיים liblog cc_library. השימוש במאפיין stem במקרה הזה מבטיח ששם קובץ הפלט יהיה liblog.* ולא liblog_rust.*.

srcs

srcs מכיל קובץ מקור יחיד שמייצג את נקודת הכניסה למודול (בדרך כלל main.rs או lib.rs). הקובץ rustc מטפל בהתאמת נתונים (resolve) ובגילוי של כל שאר קובצי המקור שנדרשים לקומפילציה, והם מפורטים בקובץ deps שנוצר.

אם אפשר, כדאי להימנע משימוש כזה בקוד של הפלטפורמה. מידע נוסף זמין במאמר בנושא מחוללי קוד.

crate_name

crate_name מגדיר את המטא-נתונים של שם התיבה באמצעות הדגל rustc --crate_name במודולים שמייצרים ספריות, השם חייב להיות זהה לשם ה-crate הצפוי שמשמש בקוד המקור. לדוגמה, אם יש הפניה למודול libfoo_bar בקוד המקור בתור extern crate foo_bar, אז חובה להגדיר את crate_name: "foo_bar".

המאפיין הזה משותף לכל המודולים של rust_*, אבל הוא נדרש למודולים שמפיקים ספריות של Rust (כמו rust_library, ‏ rust_ffi, ‏ rust_bindgen, ‏ rust_protobuf ו-rust_proc_macro). המודולים האלה אוכפים דרישות של rustc לגבי הקשר בין crate_name לבין שם קובץ הפלט. מידע נוסף זמין בקטע Library Modules.

lints

הכלי לבדיקת קוד (linter) של rustc מופעל כברירת מחדל לכל סוגי המודולים, למעט מחוללי קוד. חלק מהגדרות ה-lint מוגדרות ומשמשות לאימות המקור של המודול. הערכים האפשריים של קבוצות כאלה של בדיקות Lint הם:

  • default קבוצת ברירת המחדל של בדיקות Lint, בהתאם למיקום המודול
  • android קבוצת ה-lint הכי מחמירה שחלה על כל הקוד של פלטפורמת Android
  • vendor a relaxed set of lints applied to vendor code
  • none כדי להתעלם מכל האזהרות והשגיאות של Lint

clippy_lints

כלי ה-linter של Clippy מופעל כברירת מחדל גם לכל סוגי המודולים, למעט מחוללי מקורות. מוגדרות כמה קבוצות של בדיקות Lint, שמשמשות לאימות המקור של המודול. אלה כמה ערכים אפשריים:

  • default קבוצת ברירת המחדל של בדיקות ה-linting, בהתאם למיקום המודול
  • android קבוצת ה-lint הכי מחמירה שחלה על כל הקוד של פלטפורמת Android
  • vendor a relaxed set of lints applied to vendor code
  • none כדי להתעלם מכל האזהרות והשגיאות של Lint

מהדורה

edition מגדיר את מהדורת Rust שבה יש להשתמש כדי לקמפל את הקוד הזה. הערך הזה דומה לגרסאות std של C ו-C++. הערכים האפשריים הם 2015, 2018 ו-2021 (ברירת מחדל).

דגלים

flags: רשימה של דגלים שיועברו אל rustc במהלך ההידור.

ld_flags

ld-flags: רשימת מחרוזות של דגלים להעברה ל-linker בזמן הידור המקור. הם מועברים באמצעות הדגל -C linker-args rustc. ‫clang משמש כחלק הקדמי של הכלי לקישור, ומפעיל את lld לקישור בפועל.

תכונות

features היא רשימת מחרוזות של תכונות שצריך להפעיל במהלך ההידור. הערך הזה מועבר אל rustc על ידי --cfg 'feature="foo"'. רוב התכונות הן מצטברות, ולכן במקרים רבים הן כוללות את כל התכונות שנדרשות על ידי כל המודולים התלויים. עם זאת, במקרים שבהם התכונות הן בלעדיות זו לזו, צריך להגדיר מודולים נוספים בכל קובצי ה-build שמספקים תכונות סותרות.

cfgs

cfgs: רשימת מחרוזות של דגלים שיופעלו במהלך ההידור.cfg הנתונים האלה מועברים אל rustc על ידי --cfg foo ו---cfg "fizz=buzz".

מערכת build מגדירה באופן אוטומטי דגלים מסוימים של cfg במצבים מסוימים, שמפורטים בהמשך:

  • במודולים שנבנו כ-dylib, הערך של android_dylib cfg מוגדר.

  • במודולים שמשתמשים ב-VNDK, ההגדרה android_vndk cfg מוגדרת. היא דומה להגדרה של __ANDROID_VNDK__ ב-C++.

רצועה

strip קובעת אם קובץ הפלט יוסר (אם רלוונטי) ובאיזה אופן. אם ההגדרה הזו לא מוגדרת, ברירת המחדל של מודולי המכשיר היא להסיר את כל הנתונים חוץ מנתוני ניפוי הבאגים המינימליים. כברירת מחדל, מודולים של מארחים לא מסירים סמלים. הערכים התקפים כוללים none כדי להשבית את ההסרה, ו-all כדי להסיר הכול, כולל מידע על ניפוי באגים. ערכים נוספים אפשר למצוא בהפניה למודולים של Soong.

host_supported

במודולים של מכשירים, הפרמטר host_supported מציין אם המודול צריך לספק גם וריאציה של המארח.

הגדרת יחסי תלות של הפרויקט בספריות

מודולים של Rust יכולים להיות תלויים בספריות של CC ושל Rust באמצעות המאפיינים הבאים:

שם המאפיין תיאור
rustlibs רשימה של מודולי rust_library שהם גם תלויות. מומלץ להשתמש בשיטה הזו להצהרה על תלות, כי היא מאפשרת למערכת build לבחור את הקישור המועדף. (ראו קישור לספריות Rust בהמשך)
rlibs רשימה של מודולים של rust_library שצריך לקשר באופן סטטי בתור rlibs. (חשוב להיזהר כשמשתמשים באפשרות הזו. מידע נוסף מופיע בקטע קישור לספריות Rust בהמשך).
shared_libs רשימה של מודולים cc_library שצריכים להיות מקושרים באופן דינמי כספריות משותפות.
static_libs רשימה של מודולים cc_library שצריך לקשר באופן סטטי כספריות סטטיות.
whole_static_libs רשימה של מודולים cc_library שיש לקשר באופן סטטי כספריות סטטיות ולכלול אותם בשלמותם בספרייה שמתקבלת. עבור rust_ffi_static וריאציות, whole_static_libraries ייכללו בארכיון הספרייה הסטטית שיתקבל. במקרה של וריאציות של rust_library_rlib, ספריות whole_static_libraries ייכללו בחבילה של ספריית rlib שמתקבלת.

כשמקשרים לספריות Rust, מומלץ לעשות זאת באמצעות המאפיין rustlibs ולא באמצעות rlibs או dylibs, אלא אם יש סיבה ספציפית לעשות זאת. כך מערכת ה-Build יכולה לבחור את הקישור הנכון על סמך מה שנדרש למודול הבסיס, והסיכוי שעץ התלות יכיל גם את גרסת rlib וגם את גרסת dylib של ספרייה (מה שיגרום לכשל בהידור) יקטן.

תכונות שלא נתמכות ותכונות עם תמיכה מוגבלת

הספרייה Rust של Soong מציעה תמיכה מוגבלת בתמונות ובצילומים של vendor ושל vendor_ramdisk. עם זאת, יש תמיכה ב-staticlibs,‏ cdylibs,‏ rlibs ו-binaries. לגבי יעדי בניית תמונות של ספקים, המאפיין android_vndk cfg מוגדר. אפשר להשתמש בזה בקוד אם יש הבדלים בין יעדי המערכת ליעדי הספק. rust_proc_macros לא נכללים בצילומי מצב של ספקים. אם אתם מסתמכים על הנתונים האלה, הקפידו להשתמש בבקרת גרסאות מתאימה.

אין תמיכה בתמונות של מוצרים, VNDK ושיחזור.

גרסאות build מצטברות

מפתחים יכולים להפעיל את ההידור המצטבר של מקור Rust על ידי הגדרת משתנה הסביבה SOONG_RUSTC_INCREMENTAL לערך true.

אזהרה: אין ערובה לכך שייווצרו קבצים בינאריים זהים לאלה שנוצרו על ידי buildbots. הכתובות של הפונקציות או הנתונים שכלולים בקובצי האובייקט עשויות להיות שונות. כדי לוודא שהארטיפקטים שנוצרו זהים לחלוטין לאלה שנבנו על ידי התשתית של EngProd, לא מגדירים ערך.