הדף הזה מספק תמונה כללית של האופן שבו יש תמיכה במקור שנוצר ואיך אפשר להשתמש בו במערכת ה-build.
כל הגנרטורים של מקורות מספקים פונקציונליות דומה של מערכת build. שלושת תרחישי השימוש ליצירת מקורות שנתמכים במערכת ה-build יוצרים קישורי C באמצעות bindgen, ממשקי AIDL וממשקי protobuf.
ארגזים מהמקור שנוצר
כל מודול חלודה שיוצר קוד מקור יכול לשמש כארגז (Crate), בדיוק כמו
אם הוא הוגדר כ-rust_library
. (פירוש הדבר הוא שאפשר להגדיר
תלויה בנכסים rustlibs
, rlibs
ו-dylibs
.) דפוס השימוש הטוב ביותר בקוד פלטפורמה הוא להשתמש במקור שנוצר כ-crate. על אף
יש תמיכה במאקרו include!
עבור המקור שנוצר, והמטרה העיקרית שלו היא
תומכים בקוד של צד שלישי שנמצא ב-external/
.
יש מקרים שבהם קוד הפלטפורמה עדיין עשוי להשתמש במקור שנוצר באמצעות
המאקרו include!()
, למשל כשמשתמשים במודול genrule
כדי ליצור מקור
באופן ייחודי.
משתמשים ב-include!() כדי לכלול את המקור שנוצר
השימוש במקור שנוצר כארגז חול מתואר על הדוגמאות בכל
(בהתאמה) לדף המודול. בקטע הזה מוסבר איך להפנות למקור שנוצר באמצעות המאקרו include!()
. חשוב לזכור שהתהליך הזה דומה לכל הגנרטורים של מקורות הנתונים.
דרישה מוקדמת
הדוגמה הזו מבוססת על ההנחה שהגדרתם מודול rust_bindgen
(libbuzz_bindgen
) ואפשר להמשיך לשלבים להכללת מקור שנוצר כדי להשתמש במאקרו include!()
. אם לא עשיתם זאת, היכנסו למאמר הגדרה של מודול קישור חלודה,
יוצרים libbuzz_bindgen
ואז חוזרים לכאן.
שימו לב שהחלקים של קובץ ה-build רלוונטיים לכל הגנרטורים של מקורות קוד.
שלבים להכללת המקור שנוצר
יוצרים external/rust/hello_bindgen/Android.bp
עם התכנים הבאים:
rust_binary {
name: "hello_bzip_bindgen_include",
srcs: [
// The primary rust source file must come first in this list.
"src/lib.rs",
// The module providing the bindgen bindings is
// included in srcs prepended by ":".
":libbuzz_bindgen",
],
// Dependencies need to be redeclared when generated source is used via srcs.
shared_libs: [
"libbuzz",
],
}
יוצרים את external/rust/hello_bindgen/src/bindings.rs
עם התוכן הבא:
#![allow(clippy::all)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused)]
#![allow(missing_docs)]
// Note that "bzip_bindings.rs" here must match the source_stem property from
// the rust_bindgen module.
include!(concat!(env!("OUT_DIR"), "/bzip_bindings.rs"));
יוצרים את external/rust/hello_bindgen/src/lib.rs
עם התוכן הבא:
mod bindings;
fn main() {
let mut x = bindings::foo { x: 2 };
unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}
למה ארגזי ארגזים למקור שנוצר
בניגוד למהדרי C/C++, rustc
מקבל רק קובץ מקור אחד שמייצג נקודת כניסה לספרייה או לקובץ בינארי. המערכת מצפה שהמבנה של עץ המקור יהיה כזה שאפשר יהיה לזהות בו באופן אוטומטי את כל קובצי המקור הנדרשים. כלומר, צריך למקם את המקור שנוצר בעץ המקור, או לספק אותו באמצעות הוראה של include במקור:
include!("/path/to/hello.rs");
קהילת Rust מסתמכת על סקריפטים של build.rs
ועל הנחות לגבי סביבת ה-build של Cargo כדי לפתור את ההבדל הזה.
במהלך גרסת ה-build, הפקודה cargo
מגדירה משתנה סביבה OUT_DIR
שבו build.rs
סקריפטים צפויים למקם את קוד המקור שנוצר. משתמשים בפקודה הבאה כדי לכלול את קוד המקור:
include!(concat!(env!("OUT_DIR"), "/hello.rs"));
הפעולה הזו מציגה אתגר ל-Songg, כשהפלט של כל מודול מוצב
ספריית out/
משלהם1. אין OUT_DIR
אחד שבו
של יחסי התלות פלט את המקור שלהם.
לגבי קוד פלטפורמה, AOSP מעדיפה את המקור שנוצר באמצעות אריזה לתוך ארגז שיכול לייבא, מכמה סיבות:
- מניעת התנגשות בין שמות של קובצי מקור שנוצרו.
- הפחתת קוד סטנדרטי עשו צ'ק-אין בעץ שדורש תחזוקה. כל פלטת חימום שמיועדת שנדרשות כדי לגרום להדרת המקור שנוצר שאפשר לנהל אותם בצורה מרוכזת בתוך ארגז.
- נמנעים מאינטראקציות מרומזות2 בין הקוד שנוצר לבין הכלי שסביבו.
- הפחתת הלחץ על הזיכרון והדיסק באמצעות קישור דינמי של מקורות נפוצים שנוצרים.
כתוצאה מכך, כל סוגי המודולים ליצירת קוד מקור ב-Rust ב-Android יוצרים קוד שאפשר לקמפל ולהשתמש בו כ-crate.
בקרוב יש תמיכה בארגזים של צד שלישי ללא שינוי, אם הכול
יחסי התלות של המקור שנוצרו עבור מודול מועתקים למודול יחיד לכל מודול
דומה ל-Cargo. במקרים כאלה, ההגדרה 'סונג' מגדירה את משתנה הסביבה OUT_DIR
לספרייה הזאת בעת הידור המודול, כך שניתן יהיה למצוא את המקור שנוצר.
עם זאת, מהסיבות שתיארנו קודם, מומלץ להשתמש רק
את המנגנון הזה בקוד הפלטפורמה, כאשר הוא הכרחי.
-
אין בעיה עם שפות C/C++ ושפות דומות, כי הנתיב למקור שנוצר מסופק ישירות למהדר.↩
-
מכיוון ש-
include!
פועל על-ידי הכללה טקסט, הוא עשוי להתייחס לערכים מ- את מרחב השמות המצורף, לשנות את מרחב השמות או להשתמש במבנים כמו#![foo]
. קשה לנהל אינטראקציות מרומזות כאלה. העדפה תמיד כאשר ממש נדרשת אינטראקציה עם שאר התיבה. ↩