מערכת הבנייה תומכת ביצירת כריכות bindgen דרך סוג המודול rust_bindgen
. Bindgen מספק כריכות Rust FFI לספריות C (עם תמיכה מוגבלת ב-C++, הדורשת הגדרת המאפיין cppstd
).
שימוש בסיסי ב-rust_bindgen
להלן דוגמה כיצד להגדיר מודול המשתמש ב-bindgen, וכיצד להשתמש במודול זה בתור ארגז. אם אתה צריך להשתמש ב-bindgen bindings דרך מאקרו include!()
, כגון עבור קוד חיצוני, עיין בדף Source Generators .
ספריית C לדוגמה להתקשר מ- Rust
להלן ספריית C לדוגמה המגדירה מבנה ופונקציה לשימוש ב-Rust.
external/rust/libbuzz/libbuzz.h
typedef struct foo {
int x;
} foo;
void fizz(int i, foo* cs);
external/rust/libbuzz/libbuzz.c
#include <stdio.h>
#include "libbuzz.h"
void fizz(int i, foo* my_foo){
printf("hello from c! i = %i, my_foo->x = %i\n", i, my_foo->x);
}
הגדר מודול rust_bindgen
הגדר כותרת עטיפה, external/rust/libbuzz/libbuzz_wrapper.h
, הכוללת את כל הכותרות הרלוונטיות:
// Include headers that are required for generating bindings in a wrapper header.
#include "libbuzz.h"
הגדר את קובץ Android.bp
כ- external/rust/libbuzz/Android.bp
:
cc_library {
name: "libbuzz",
srcs: ["libbuzz.c"],
}
rust_bindgen {
name: "libbuzz_bindgen",
// Crate name that's used to generate the rust_library variants.
crate_name: "buzz_bindgen",
// Path to the wrapper source file.
wrapper_src: "libbuzz_wrapper.h",
// 'source_stem' controls the output filename.
// This is the filename that's used in an include! macro.
//
// In this case, we just use "bindings", which produces
// "bindings.rs".
source_stem: "bindings",
// Bindgen-specific flags and options to customize the bindings.
// See the bindgen manual for more information.
bindgen_flags: ["--verbose"],
// Clang flags to be used when generating the bindings.
cflags: ["-DSOME_FLAG"],
// Shared, static, and header libraries which export the necessary
// include directories must be specified.
//
// These libraries will also be included in the crate if static,
// or propagated to dependents if shared.
// static_libs: ["libbuzz"]
// header_libs: ["libbuzz"]
shared_libs: ["libbuzz"],
}
למידע נוסף על שימוש בדגלי bindgen, עיין בסעיף המדריך של bindgen בנושא התאמה אישית של כריכות שנוצרו .
אם השתמשת בסעיף זה כדי להגדיר מודול rust_bindgen
כתנאי מוקדם לשימוש במאקרו include!()
, חזור אל Prerequisite בדף Source Generators. אם לא, המשך לסעיפים הבאים.
השתמש בכריכות בתור ארגז
צור external/rust/hello_bindgen/Android.bp
עם התוכן הבא:
rust_binary {
name: "hello_bindgen",
srcs: ["main.rs"],
// Add the rust_bindgen module as if it were a rust_library dependency.
rustlibs: ["libbuzz_bindgen"],
}
צור external/rust/hello_bindgen/src/main.rs
עם התוכן הבא:
//! Example crate for testing bindgen bindings
fn main() {
let mut x = buzz_bindgen::foo { x: 2 };
unsafe { buzz_bindgen::fizz(1, &mut x as *mut buzz_bindgen::foo) }
}
לבסוף, קרא ל- m hello_bindgen
כדי לבנות את הבינארי.
בדוק כריכות Bindgen
כריכות Bindgen מכילות בדרך כלל מספר מבחני פריסה שנוצרו כדי למנוע אי-התאמה של פריסת זיכרון. AOSP ממליצה להגדיר מודול בדיקה עבור בדיקות אלו, ושהבדיקות יפעלו כחלק מחבילת הבדיקות הרגילה של הפרויקט שלך.
ניתן לייצר בקלות בינארי בדיקה עבור אלה על ידי הגדרת מודול rust_test
ב- external/rust/hello_bindgen/Android.bp
:
rust_test {
name: "bindings_test",
srcs: [
":libbuzz_bindgen",
],
crate_name: "buzz_bindings_test",
test_suites: ["general-tests"],
auto_gen_config: true,
// Be sure to disable lints as the generated source
// is not guaranteed to be lint-free.
clippy_lints: "none",
lints: "none",
}
נראות והצמדה
כריכות שנוצרו הן בדרך כלל קטנות מאוד, מכיוון שהן מורכבות מהגדרות סוג, חתימות פונקציות וקבועים קשורים. כתוצאה מכך, זה בדרך כלל בזבזני לקשר ספריות אלה באופן דינמי. השבתנו קישור דינמי עבור מודולים אלה כך ששימוש בהם באמצעות rustlibs
יבחר אוטומטית גרסה סטטית.
כברירת מחדל, למודול rust_bindgen
יש מאפיין visibility
של [":__subpackages__"]
, אשר יאפשר רק למודולים באותו קובץ Android.bp
או לאלה שמתחתיו בהיררכיית הספריות לראות אותו. זה משרת שתי מטרות:
- זה מונע שימוש בקשרי C גולמיים במקומות אחרים בעץ.
- זה מונע בעיות של קישור יהלומים עם שילוב של קישור סטטי ודינאמי.
בדרך כלל, עליך לספק ספריית מעטפת בטוחה מסביב למודול שנוצר שהוספת באותו עץ ספריות כמו ה-bindings שמיועד למפתחים אחרים להשתמש. אם זה לא עובד במקרה השימוש שלך, אתה יכול להוסיף חבילות נוספות לנראות . בעת הוספת היקפי נראות נוספים, אנא הקפד שלא תוסיף שני היקפים שעשויים להיות מקושרים לאותו תהליך בעתיד, מכיוון שזה עלול להיכשל בקישור.
מאפיינים בולטים של rust_bindgen
המאפיינים המוגדרים להלן מתווספים למאפיינים המשותפים החשובים החלים על כל המודולים. אלה חשובים במיוחד למודולי Rust bindgen, או שהם מציגים התנהגות ייחודית ספציפית לסוג המודול rust_bindgen
.
stam, name, crate_name
rust_bindgen
מייצר גרסאות של ספרייה, כך שהן חולקות את אותן דרישות עם המודולים rust_library
עבור המאפיינים stem
, name
ו- crate_name
. ראה מאפיינים בולטים של ספריית חלודה לעיון.
wrapper_src
זהו הנתיב היחסי לקובץ כותרות עטיפה הכולל את הכותרות הנדרשות עבור כריכות אלו. סיומת הקובץ קובעת כיצד לפרש את הכותרת וקובעת באיזה דגל -std
להשתמש כברירת מחדל. ההנחה היא שזו כותרת C אלא אם כן הסיומת היא .hh
או .hpp
. אם לכותרת C++ שלך חייבת להיות סיומת אחרת, הגדר את המאפיין cpp_std
כדי לעקוף את התנהגות ברירת המחדל שמניחה שהקובץ הוא קובץ C.
מקור_סטם
זהו שם הקובץ של קובץ המקור שנוצר . שדה זה חייב להיות מוגדר, גם אם אתה משתמש ב-bindings בתור ארגז, מכיוון שמאפיין stem
שולט רק בשם קובץ הפלט עבור גרסאות הספרייה שנוצרו. אם מודול תלוי במחוללי מקור מרובים (כגון bindgen
ו- protobuf
) כמקור ולא בתור ארגזים דרך rustlibs
, עליך לוודא שלכל מחוללי המקור שהם תלות של אותו מודול יש ערכי source_stem
ייחודיים. מודולים תלויים מעתיקים מקורות מכל התלות SourceProvider
המוגדרות ב- srcs
לספריית OUT_DIR
משותפת, כך שהתנגשויות ב- source_stem
יגרמו להחלפת קבצי המקור שנוצרו בספריית OUT_DIR
.
c_std
זוהי מחרוזת המייצגת באיזו גרסה סטנדרטית C להשתמש. ערכים חוקיים מפורטים להלן:
- גרסה ספציפית, כגון
"gnu11"
. -
"experimental"
, שהוא ערך שהוגדר על ידי מערכת ה-build ב-build/soong/cc/config/global.go
, עשוי להשתמש בגרסאות טיוטה כמו C++1z כשהן זמינות. - בטל או
""
, המציין שיש להשתמש בברירת המחדל של מערכת הבנייה.
אם זה מוגדר, מתעלמים מסיומת הקובץ ומניחים שהכותרת היא כותרת C. לא ניתן להגדיר זאת בו-זמנית עם cpp_std
.
cpp_std
cpp_std
היא מחרוזת המייצגת באיזו גרסה סטנדרטית C להשתמש. ערכים חוקיים:
- גרסה ספציפית, כגון
"gnu++11"
-
"experimental"
, שהוא ערך שהוגדר על ידי מערכת ה-build ב-build/soong/cc/config/global.go
, עשוי להשתמש בגרסאות טיוטה כמו C++1z כשהן זמינות. - בטל או
""
, המציין שיש להשתמש בברירת המחדל של מערכת הבנייה.
אם זה מוגדר, מתעלמים מסיומת הקובץ ומניחים שהכותרת היא כותרת C++. לא ניתן להגדיר זאת בו-זמנית עם c_std
.
cflags
cflags
מספק רשימת מחרוזות של דגלי Clang הנדרשים כדי לפרש נכון את הכותרות.
custom_bindgen
עבור מקרי שימוש מתקדמים, ניתן להשתמש ב-bindgen כספרייה, המספקת API שניתן לתמרן כחלק מבינארי Rust מותאם אישית. השדה custom_bindgen
לוקח את שם המודול של מודול rust_binary_host
, המשתמש ב-bindgen API במקום הבינארי הרגיל bindgen
.
בינארי מותאם אישית זה חייב לצפות לטיעונים בצורה דומה ל- bindgen
, כגון
$ my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]
רוב זה מטופל על ידי ספריית bindgen
עצמה. כדי לראות דוגמה לשימוש זה, בקר ב-extern/rust/crates/libsqlite3-sys/android/build.rs .
בנוסף, הסט המלא של מאפייני הספרייה זמין כדי לשלוט על הידור של הספרייה, אם כי לעתים נדירות יש צורך בהגדרה או שינוי של אלה.