Halaman ini memberikan gambaran mendetail tentang bagaimana sumber yang dihasilkan didukung dan dan cara penggunaannya dalam sistem build.
Semua generator sumber menyediakan fungsi sistem build yang serupa. Tiga Kasus penggunaan pembuatan sumber yang didukung sistem build menghasilkan binding C menggunakan bindgen, antarmuka AIDL, dan antarmuka protobuf.
Peti dari sumber yang dihasilkan
Setiap modul Rust yang menghasilkan kode sumber dapat digunakan sebagai peti, persis seperti
jika ditentukan sebagai rust_library
. (Ini berarti, hal ini dapat didefinisikan sebagai
dependensi dalam properti rustlibs
, rlibs
, dan dylibs
.) Penggunaan terbaik
untuk kode platform adalah menggunakan
sumber yang dihasilkan sebagai peti. Meskipun
Makro include!
didukung untuk sumber yang dihasilkan, tujuan utamanya adalah untuk
mendukung kode pihak ketiga yang berada di external/
.
Ada kasus di mana kode platform masih
menggunakan sumber yang dihasilkan melalui
Makro include!()
, seperti saat Anda menggunakan modul genrule
untuk membuat sumber
dengan cara yang unik.
Menggunakan include!() untuk menyertakan sumber yang dihasilkan
Penggunaan sumber yang dihasilkan sebagai tempat
dibahas oleh contoh-contoh di setiap
(masing-masing). Bagian ini menunjukkan cara mereferensikan sumber yang dihasilkan
melalui makro include!()
. Perhatikan bahwa proses ini serupa untuk semua sumber
generator.
Prasyarat
Contoh ini didasarkan pada asumsi bahwa Anda telah menentukan rust_bindgen
modul (libbuzz_bindgen
) dan dapat melanjutkan ke Langkah-langkah untuk menyertakan sumber yang dihasilkan
untuk menggunakan makro include!()
. Jika belum, buka Mendefinisikan modul bindgen rust,
buat libbuzz_bindgen
, lalu kembali ke sini.
Perhatikan, bagian file build dari ini berlaku untuk semua generator sumber.
Langkah-langkah untuk menyertakan sumber yang dihasilkan
Buat external/rust/hello_bindgen/Android.bp
dengan konten berikut:
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",
],
}
Buat external/rust/hello_bindgen/src/bindings.rs
dengan konten berikut:
#![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"));
Buat external/rust/hello_bindgen/src/lib.rs
dengan konten berikut:
mod bindings;
fn main() {
let mut x = bindings::foo { x: 2 };
unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}
Alasan pembuatan kotak untuk sumber yang dihasilkan
Tidak seperti compiler C/C++, rustc
hanya menerima satu file sumber
yang mewakili titik entri
ke biner atau {i>library<i}. Diharapkan bahwa sumber
struktur hierarki sedemikian rupa sehingga semua file sumber yang diperlukan dapat otomatis
ditemukan. Artinya, sumber yang dihasilkan harus ditempatkan di sumber
hierarki, atau disediakan melalui perintah include di sumber:
include!("/path/to/hello.rs");
Komunitas Rust bergantung pada skrip build.rs
, dan asumsi tentang
lingkungan build Cargo, untuk bekerja dengan perbedaan ini.
Saat build, perintah cargo
menetapkan variabel lingkungan OUT_DIR
di mana skrip build.rs
diharapkan untuk menempatkan kode sumber yang dihasilkan. Gunakan
perintah berikut untuk menyertakan kode sumber:
include!(concat!(env!("OUT_DIR"), "/hello.rs"));
Ini menimbulkan tantangan bagi Soong karena {i>output<i} untuk setiap modul ditempatkan di
direktori out/
tersendiri1. Tidak ada satu OUT_DIR
dengan
dependensi menghasilkan output berupa
sumber yang dihasilkannya.
Untuk kode platform, AOSP lebih memilih pengemasan sumber yang dihasilkan ke dalam peti yang dapat diimpor, karena beberapa alasan:
- Mencegah nama file sumber yang dihasilkan bentrok.
- Mengurangi kode boilerplate memeriksa seluruh pohon yang membutuhkan pemeliharaan. Boilerplate yang yang diperlukan untuk membuat kompilasi sumber yang dihasilkan ke dalam kandang dapat dikelola secara terpusat.
- Hindari interaksi2 implisit antara kode yang dihasilkan dan container di sekitarnya.
- Kurangi tekanan pada memori dan disk dengan secara dinamis menautkan sumber buatan yang umum digunakan.
Akibatnya, semua jenis modul pembuatan sumber Rust Android menghasilkan kode
yang dapat dikompilasi dan digunakan sebagai peti.
Soong masih mendukung penyimpanan pihak ketiga tanpa modifikasi jika semuanya
dependensi sumber yang dihasilkan untuk modul disalin ke dalam satu modul
seperti Cargo. Dalam kasus tersebut, Soong menetapkan variabel lingkungan OUT_DIR
ke direktori itu saat mengompilasi modul, sehingga sumber yang dihasilkan dapat ditemukan.
Namun, untuk alasan yang telah dijelaskan, praktik terbaiknya hanya menggunakan
mekanisme ini dalam kode platform
ketika benar-benar diperlukan.
-
Hal ini tidak menimbulkan masalah pada C/C++ dan bahasa serupa, karena ke sumber yang dihasilkan akan disediakan langsung ke compiler. ↩
-
Karena menggunakan penyertaan tekstual,
include!
dapat mereferensikan nilai dari namespace yang mencakupnya, memodifikasi namespace, atau menggunakan konstruksi seperti#![foo]
. Interaksi implisit ini mungkin sulit dikelola. Selalu pilih makro ketika interaksi dengan seluruh kandang benar-benar diperlukan.↩