Generator sumber

Halaman ini memberikan gambaran tingkat tinggi tentang bagaimana sumber yang dihasilkan didukung dan bagaimana sumber tersebut dapat digunakan dalam sistem build.

Semua generator sumber menyediakan fungsionalitas sistem build yang serupa. Tiga kasus penggunaan pembuatan sumber yang didukung sistem build menghasilkan pengikatan 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 didefinisikan sebagai rust_library . (Ini berarti dapat didefinisikan sebagai ketergantungan pada properti rustlibs , rlibs , dan dylibs .) Pola penggunaan terbaik untuk kode platform adalah dengan menggunakan sumber yang dihasilkan sebagai peti. Meskipun include! makro didukung untuk sumber yang dihasilkan, tujuan utamanya adalah untuk mendukung kode pihak ketiga yang berada di external/ .

Ada beberapa kasus di mana kode platform mungkin masih menggunakan sumber yang dihasilkan melalui makro include!() , misalnya saat Anda menggunakan modul genrule untuk menghasilkan sumber dengan cara yang unik.

Gunakan include!() untuk memasukkan sumber yang dihasilkan

Menggunakan sumber yang dihasilkan sebagai peti tercakup dalam contoh di setiap halaman modul tertentu (masing-masing). Bagian ini menunjukkan cara mereferensikan sumber yang dihasilkan melalui makro include!() . Perhatikan bahwa proses ini serupa untuk semua generator sumber.

Prasyarat

Contoh ini didasarkan pada asumsi bahwa Anda telah mendefinisikan modul rust_bindgen ( libbuzz_bindgen ) dan dapat melanjutkan ke Langkah-langkah untuk menyertakan sumber yang dihasilkan untuk menggunakan makro include!() . Jika belum, silakan buka Mendefinisikan modul Rust Bindgen , buat libbuzz_bindgen , lalu kembali ke sini.

Perhatikan bahwa bagian file build ini berlaku untuk semua generator sumber.

Langkah-langkah untuk memasukkan sumber yang dihasilkan

Buat external/rust/hello_bindgen/Android.bp dengan isi sebagai 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 isi sebagai 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 isi sebagai berikut:

mod bindings;

fn main() {
    let mut x = bindings::foo { x: 2 };
    unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}

Mengapa peti untuk sumber yang dihasilkan

Tidak seperti kompiler C/C++, rustc hanya menerima satu file sumber yang mewakili titik masuk ke biner atau perpustakaan. Pohon sumber diharapkan disusun sedemikian rupa sehingga semua file sumber yang diperlukan dapat ditemukan secara otomatis. Artinya, sumber yang dihasilkan harus ditempatkan di pohon sumber, atau disediakan melalui arahan penyertaan dalam sumber:

include!("/path/to/hello.rs");

Komunitas Rust bergantung pada skrip build.rs , dan asumsi tentang lingkungan build Cargo, untuk mengatasi perbedaan ini . Ketika dibangun, perintah cargo menetapkan variabel lingkungan OUT_DIR ke dalam skrip build.rs yang diharapkan untuk menempatkan kode sumber yang dihasilkan. Gunakan perintah berikut untuk memasukkan kode sumber:

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

Hal ini menghadirkan tantangan bagi Soong karena keluaran untuk setiap modul ditempatkan di direktori out/ 1 masing-masing. Tidak ada satu pun OUT_DIR tempat dependensi menampilkan sumber yang dihasilkannya.

Untuk kode platform, AOSP lebih memilih mengemas sumber yang dihasilkan ke dalam peti yang dapat diimpor, karena beberapa alasan:

  • Cegah nama file sumber yang dihasilkan bertabrakan.
  • Kurangi kode boilerplate yang check-in di seluruh pohon yang memerlukan pemeliharaan. Boilerplate apa pun yang diperlukan untuk membuat kompilasi sumber yang dihasilkan ke dalam peti dapat dikelola secara terpusat.
  • Hindari 2 interaksi implisit antara kode yang dihasilkan dan peti di sekitarnya.
  • Kurangi tekanan pada memori dan disk dengan menghubungkan secara dinamis sumber-sumber yang umum digunakan.

Hasilnya, semua jenis modul pembuatan sumber Rust Android menghasilkan kode yang dapat dikompilasi dan digunakan sebagai peti . Soong masih mendukung peti pihak ketiga tanpa modifikasi jika semua dependensi sumber yang dihasilkan untuk sebuah modul disalin ke dalam satu direktori per modul, mirip dengan Cargo. Dalam kasus seperti itu, Soong menyetel variabel lingkungan OUT_DIR ke direktori tersebut saat mengkompilasi modul, sehingga sumber yang dihasilkan dapat ditemukan. Namun, karena alasan yang telah dijelaskan, praktik terbaiknya adalah hanya menggunakan mekanisme ini dalam kode platform jika benar-benar diperlukan.


  1. Hal ini tidak menimbulkan masalah apa pun untuk C/C++ dan bahasa serupa, karena jalur ke sumber yang dihasilkan disediakan langsung ke kompiler.

  2. Sejak include! bekerja dengan penyertaan tekstual, ia mungkin mereferensikan nilai dari namespace terlampir, memodifikasi namespace, atau menggunakan konstruksi seperti #![foo] . Interaksi implisit ini mungkin sulit dipertahankan. Selalu pilih makro ketika interaksi dengan anggota peti lainnya benar-benar diperlukan.

,

Halaman ini memberikan gambaran tingkat tinggi tentang bagaimana sumber yang dihasilkan didukung dan bagaimana sumber tersebut dapat digunakan dalam sistem build.

Semua generator sumber menyediakan fungsionalitas sistem build yang serupa. Tiga kasus penggunaan pembuatan sumber yang didukung sistem build menghasilkan pengikatan 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 didefinisikan sebagai rust_library . (Ini berarti dapat didefinisikan sebagai ketergantungan pada properti rustlibs , rlibs , dan dylibs .) Pola penggunaan terbaik untuk kode platform adalah dengan menggunakan sumber yang dihasilkan sebagai peti. Meskipun include! makro didukung untuk sumber yang dihasilkan, tujuan utamanya adalah untuk mendukung kode pihak ketiga yang berada di external/ .

Ada beberapa kasus di mana kode platform mungkin masih menggunakan sumber yang dihasilkan melalui makro include!() , misalnya saat Anda menggunakan modul genrule untuk menghasilkan sumber dengan cara yang unik.

Gunakan include!() untuk memasukkan sumber yang dihasilkan

Menggunakan sumber yang dihasilkan sebagai peti tercakup dalam contoh di setiap halaman modul tertentu (masing-masing). Bagian ini menunjukkan cara mereferensikan sumber yang dihasilkan melalui makro include!() . Perhatikan bahwa proses ini serupa untuk semua generator sumber.

Prasyarat

Contoh ini didasarkan pada asumsi bahwa Anda telah mendefinisikan modul rust_bindgen ( libbuzz_bindgen ) dan dapat melanjutkan ke Langkah-langkah untuk menyertakan sumber yang dihasilkan untuk menggunakan makro include!() . Jika belum, silakan buka Mendefinisikan modul Rust Bindgen , buat libbuzz_bindgen , lalu kembali ke sini.

Perhatikan bahwa bagian file build ini berlaku untuk semua generator sumber.

Langkah-langkah untuk memasukkan sumber yang dihasilkan

Buat external/rust/hello_bindgen/Android.bp dengan isi sebagai 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 isi sebagai 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 isi sebagai berikut:

mod bindings;

fn main() {
    let mut x = bindings::foo { x: 2 };
    unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}

Mengapa peti untuk sumber yang dihasilkan

Tidak seperti kompiler C/C++, rustc hanya menerima satu file sumber yang mewakili titik masuk ke biner atau perpustakaan. Pohon sumber diharapkan disusun sedemikian rupa sehingga semua file sumber yang diperlukan dapat ditemukan secara otomatis. Artinya, sumber yang dihasilkan harus ditempatkan di pohon sumber, atau disediakan melalui arahan penyertaan dalam sumber:

include!("/path/to/hello.rs");

Komunitas Rust bergantung pada skrip build.rs , dan asumsi tentang lingkungan build Cargo, untuk mengatasi perbedaan ini . Ketika dibangun, perintah cargo menetapkan variabel lingkungan OUT_DIR ke dalam skrip build.rs yang diharapkan untuk menempatkan kode sumber yang dihasilkan. Gunakan perintah berikut untuk memasukkan kode sumber:

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

Hal ini menghadirkan tantangan bagi Soong karena keluaran untuk setiap modul ditempatkan di direktori out/ 1 masing-masing. Tidak ada satu pun OUT_DIR tempat dependensi menampilkan sumber yang dihasilkannya.

Untuk kode platform, AOSP lebih memilih mengemas sumber yang dihasilkan ke dalam peti yang dapat diimpor, karena beberapa alasan:

  • Cegah nama file sumber yang dihasilkan bertabrakan.
  • Kurangi kode boilerplate yang check-in di seluruh pohon yang memerlukan pemeliharaan. Boilerplate apa pun yang diperlukan untuk membuat kompilasi sumber yang dihasilkan ke dalam peti dapat dikelola secara terpusat.
  • Hindari 2 interaksi implisit antara kode yang dihasilkan dan peti di sekitarnya.
  • Kurangi tekanan pada memori dan disk dengan menghubungkan secara dinamis sumber-sumber yang umum digunakan.

Hasilnya, semua jenis modul pembuatan sumber Rust Android menghasilkan kode yang dapat dikompilasi dan digunakan sebagai peti . Soong masih mendukung peti pihak ketiga tanpa modifikasi jika semua dependensi sumber yang dihasilkan untuk sebuah modul disalin ke dalam satu direktori per modul, mirip dengan Cargo. Dalam kasus seperti itu, Soong menyetel variabel lingkungan OUT_DIR ke direktori tersebut saat mengkompilasi modul, sehingga sumber yang dihasilkan dapat ditemukan. Namun, karena alasan yang telah dijelaskan, praktik terbaiknya adalah hanya menggunakan mekanisme ini dalam kode platform jika benar-benar diperlukan.


  1. Hal ini tidak menimbulkan masalah apa pun untuk C/C++ dan bahasa serupa, karena jalur ke sumber yang dihasilkan disediakan langsung ke kompiler.

  2. Sejak include! bekerja dengan penyertaan tekstual, ia mungkin mereferensikan nilai dari namespace terlampir, memodifikasi namespace, atau menggunakan konstruksi seperti #![foo] . Interaksi implisit ini mungkin sulit dipertahankan. Selalu pilih makro ketika interaksi dengan anggota peti lainnya benar-benar diperlukan.

,

Halaman ini memberikan gambaran tingkat tinggi tentang bagaimana sumber yang dihasilkan didukung dan bagaimana sumber tersebut dapat digunakan dalam sistem build.

Semua generator sumber menyediakan fungsionalitas sistem build yang serupa. Tiga kasus penggunaan pembuatan sumber yang didukung sistem build menghasilkan pengikatan 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 didefinisikan sebagai rust_library . (Ini berarti dapat didefinisikan sebagai ketergantungan pada properti rustlibs , rlibs , dan dylibs .) Pola penggunaan terbaik untuk kode platform adalah dengan menggunakan sumber yang dihasilkan sebagai peti. Meskipun include! makro didukung untuk sumber yang dihasilkan, tujuan utamanya adalah untuk mendukung kode pihak ketiga yang berada di external/ .

Ada beberapa kasus di mana kode platform mungkin masih menggunakan sumber yang dihasilkan melalui makro include!() , misalnya saat Anda menggunakan modul genrule untuk menghasilkan sumber dengan cara yang unik.

Gunakan include!() untuk menyertakan sumber yang dihasilkan

Menggunakan sumber yang dihasilkan sebagai peti tercakup dalam contoh di setiap halaman modul tertentu (masing-masing). Bagian ini menunjukkan cara mereferensikan sumber yang dihasilkan melalui makro include!() . Perhatikan bahwa proses ini serupa untuk semua generator sumber.

Prasyarat

Contoh ini didasarkan pada asumsi bahwa Anda telah mendefinisikan modul rust_bindgen ( libbuzz_bindgen ) dan dapat melanjutkan ke Langkah-langkah untuk menyertakan sumber yang dihasilkan untuk menggunakan makro include!() . Jika belum, silakan buka Mendefinisikan modul Rust Bindgen , buat libbuzz_bindgen , lalu kembali ke sini.

Perhatikan bahwa bagian file build ini berlaku untuk semua generator sumber.

Langkah-langkah untuk memasukkan sumber yang dihasilkan

Buat external/rust/hello_bindgen/Android.bp dengan isi sebagai 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 isi sebagai 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 isi sebagai berikut:

mod bindings;

fn main() {
    let mut x = bindings::foo { x: 2 };
    unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}

Mengapa peti untuk sumber yang dihasilkan

Tidak seperti kompiler C/C++, rustc hanya menerima satu file sumber yang mewakili titik masuk ke biner atau perpustakaan. Pohon sumber diharapkan disusun sedemikian rupa sehingga semua file sumber yang diperlukan dapat ditemukan secara otomatis. Artinya, sumber yang dihasilkan harus ditempatkan di pohon sumber, atau disediakan melalui arahan penyertaan dalam sumber:

include!("/path/to/hello.rs");

Komunitas Rust bergantung pada skrip build.rs , dan asumsi tentang lingkungan build Cargo, untuk mengatasi perbedaan ini . Ketika dibangun, perintah cargo menetapkan variabel lingkungan OUT_DIR ke dalam skrip build.rs yang diharapkan untuk menempatkan kode sumber yang dihasilkan. Gunakan perintah berikut untuk memasukkan kode sumber:

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

Hal ini menghadirkan tantangan bagi Soong karena keluaran untuk setiap modul ditempatkan di direktori out/ 1 masing-masing. Tidak ada satu pun OUT_DIR tempat dependensi menampilkan sumber yang dihasilkannya.

Untuk kode platform, AOSP lebih memilih mengemas sumber yang dihasilkan ke dalam peti yang dapat diimpor, karena beberapa alasan:

  • Cegah nama file sumber yang dihasilkan bertabrakan.
  • Kurangi kode boilerplate yang check-in di seluruh pohon yang memerlukan pemeliharaan. Boilerplate apa pun yang diperlukan untuk membuat kompilasi sumber yang dihasilkan ke dalam peti dapat dikelola secara terpusat.
  • Hindari 2 interaksi implisit antara kode yang dihasilkan dan peti di sekitarnya.
  • Kurangi tekanan pada memori dan disk dengan menghubungkan secara dinamis sumber-sumber yang umum digunakan.

Hasilnya, semua jenis modul pembuatan sumber Rust Android menghasilkan kode yang dapat dikompilasi dan digunakan sebagai peti . Soong masih mendukung peti pihak ketiga tanpa modifikasi jika semua dependensi sumber yang dihasilkan untuk sebuah modul disalin ke dalam satu direktori per modul, mirip dengan Cargo. Dalam kasus seperti itu, Soong menyetel variabel lingkungan OUT_DIR ke direktori tersebut saat mengkompilasi modul, sehingga sumber yang dihasilkan dapat ditemukan. Namun, karena alasan yang telah dijelaskan, praktik terbaiknya adalah hanya menggunakan mekanisme ini dalam kode platform jika benar-benar diperlukan.


  1. Hal ini tidak menimbulkan masalah apa pun untuk C/C++ dan bahasa serupa, karena jalur ke sumber yang dihasilkan disediakan langsung ke kompiler.

  2. Sejak include! bekerja dengan penyertaan tekstual, ia mungkin mereferensikan nilai dari namespace terlampir, memodifikasi namespace, atau menggunakan konstruksi seperti #![foo] . Interaksi implisit ini mungkin sulit dipertahankan. Selalu pilih makro ketika interaksi dengan anggota peti lainnya benar-benar diperlukan.