Kaynak oluşturucular

Bu sayfada, oluşturulan kaynağın nasıl desteklendiği ve derleme sisteminde nasıl kullanılabileceğine dair genel bir bakış sunulmaktadır.

Tüm kaynak oluşturucular, benzer bir derleme sistemi işlevi sunar. Derleme sistemi tarafından desteklenen üç kaynak oluşturma kullanım alanı; bindgen, AIDL arayüzleri ve protobuf arayüzleri kullanılarak C bağlamaları oluşturmaktır.

Oluşturulan kaynaktan kutular

Kaynak kodu oluşturan her Rust modülü, rust_library olarak tanımlanmış gibi tam olarak bir paket olarak kullanılabilir. (Bu, rustlibs, rlibs ve dylibs özelliklerinde bağımlılık olarak tanımlanabileceği anlamına gelir.) Platform kodu için en iyi kullanım şekli, oluşturulan kaynağı paket olarak kullanmaktır. include! makrosu, oluşturulan kaynak için desteklense de birincil amacı external/ içinde bulunan üçüncü taraf kodu desteklemektir.

Benzersiz bir şekilde kaynak oluşturmak için genrule modülü kullanmak gibi bazı durumlarda platform kodu include!() makrosu üzerinden oluşturulan kaynağı kullanabilir.

Oluşturulan kaynağı dahil etmek için include!() işlevini kullanın

Oluşturulan kaynağın kafes olarak kullanılması, her bir spesifik modül sayfasındaki örnekler kapsamındadır. Bu bölümde, include!() makrosu aracılığıyla oluşturulan kaynağa nasıl referans verileceği gösterilmektedir. Bu sürecin tüm kaynak oluşturucular için benzer olduğunu unutmayın.

Ön Koşul

Bu örnekte, bir rust_bindgen modülü (libbuzz_bindgen) tanımladığınız ve include!() makrosunu kullanmak için Oluşturulan kaynağı dahil etme adımları'na geçebileceğiniz varsayılmaktadır. Henüz yapmadıysanız lütfen Rust bindgen modülü tanımlama başlıklı makaleyi inceleyin, libbuzz_bindgen oluşturun ve buraya dönün.

Bu dosyanın derleme dosyası bölümlerinin tüm kaynak oluşturucular için geçerli olduğunu unutmayın.

Oluşturulan kaynağı ekleme adımları

Aşağıdaki içeriklerle external/rust/hello_bindgen/Android.bp oluşturun:

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",
    ],
}

Aşağıdaki içeriklerle external/rust/hello_bindgen/src/bindings.rs oluşturun:

#![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"));

Aşağıdaki içeriklerle external/rust/hello_bindgen/src/lib.rs oluşturun:

mod bindings;

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

Oluşturulan kaynak neden oluşturulur?

C/C++ derleyicilerinden farklı olarak rustc, yalnızca bir ikili program veya kitaplığa giriş noktasını temsil eden tek bir kaynak dosyasını kabul eder. Kaynak ağacının, gerekli tüm kaynak dosyaların otomatik olarak bulunabileceği şekilde yapılandırılmasını bekler. Bu, oluşturulan kaynağın kaynak ağacına yerleştirilmesi veya kaynakta bir include yönergesi aracılığıyla sağlanması gerektiği anlamına gelir:

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

Rust topluluğu, bu farkla çalışmak için build.rs komut dosyalarına ve Cargo derleme ortamıyla ilgili varsayımlara dayanır. Derleme sırasında cargo komutu, build.rs komut dosyalarının oluşturulan kaynak kodu yerleştirmesi beklenen bir OUT_DIR ortam değişkeni ayarlar. Kaynak kodu eklemek için aşağıdaki komutu kullanın:

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

Her modülün çıkışları kendi out/ dizinine yerleştirildiği için bu durum Soong için bir sorun teşkil eder1. Bağımlılıkların, oluşturulan kaynaklarının çıktısını oluşturduğu tek bir OUT_DIR yoktur.

AOSP, platform kodu için oluşturulan kaynağı, aşağıdaki nedenlerden dolayı içe aktarılabilen bir pakete paketlemeyi tercih eder:

  • Oluşturulan kaynak dosya adlarının çakışmasını önleyin.
  • Ağaç genelinde bakım gerektiren standart kodu azaltın. Oluşturulan kaynak derlemesinin kasaya dönüştürülmesi için gereken tüm ortak belgeler merkezi olarak yönetilebilir.
  • Oluşturulan kod ile çevredeki paket arasında örtülü2 etkileşimden kaçının.
  • Sık kullanılan oluşturulan kaynakları dinamik olarak bağlayarak bellek ve disk üzerindeki baskıyı azaltın.

Sonuç olarak, Android'in Rust kaynak oluşturma modülü türlerinin tümü, derlenip paket olarak kullanılabilen kodlar oluşturur. Bir modül için oluşturulan tüm kaynak bağımlılıkları Cargo'ya benzer şekilde, modül başına tek bir dizine kopyalanıyorsa Shortg, herhangi bir değişiklik yapılmadan üçüncü taraf kasalarını desteklemeye devam etmektedir. Bu gibi durumlarda Mostg, modülü derlerken OUT_DIR ortam değişkenini bu dizine ayarlar. Böylece, oluşturulan kaynak bulunabilir. Ancak daha önce açıklanan nedenlerden dolayı, bu mekanizmanın platform kodunda yalnızca kesinlikle gerekli olduğunda kullanılması en iyi uygulamadır.


  1. Oluşturulan kaynağın yolu doğrudan derleyiciye sağlandığından bu durum C/C++ ve benzer diller için herhangi bir sorun teşkil etmez. 

  2. include!, metin dahil etme yöntemiyle çalıştığından, kapsayıcı ad alanındaki değerlere referans verebilir, ad alanını değiştirebilir veya #![foo] gibi yapıları kullanabilir. Bu örtülü etkileşimleri sürdürmek zor olabilir. Paketin geri kalanıyla etkileşim gerçekten gerekli olduğunda her zaman makroları tercih edin.