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 derleme sistemi işlevleri sağlar. 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. Oluşturulan kaynak için include! makrosu desteklenmesine rağmen birincil amacı, external/ içinde bulunan üçüncü taraf kodunu desteklemektir.

Platform kodunun, oluşturulan kaynağı include!() makrosu aracılığıyla kullanmaya devam edebileceği durumlar vardır (ör. benzersiz bir şekilde kaynak oluşturmak için genrule modülü kullandığınızda).

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

Oluşturulan kaynağı kutu olarak kullanma, her bir (ilgili) modül sayfasındaki örneklerde ele alınmıştır. Bu bölümde, oluşturulan kaynağa include!() makrosu aracılığıyla 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 için neden kutular?

C/C++ derleyicilerinin aksine rustc, yalnızca bir ikili dosyaya veya kitaplığa giriş noktasını temsil eden tek bir kaynak dosya 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 güvenir. 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, Soong için bir sorun teşkil eder1. Bağımlılıkların oluşturulan kaynağını yayınladığı 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ı önler.
  • Ağaç boyunca kaydedilen ve bakım gerektiren ortak metin kodunun sayısını azaltın. Oluşturulan kaynağın bir pakete derlenmesi için gereken tüm standart metinler 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. Soong, 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ırsa üçüncü taraf paketlerini değişiklik yapmadan desteklemeye devam eder. Bu tür durumlarda Soong, modülü derlediğinde OUT_DIR ortam değişkenini bu dizinde ayarlar. Böylece, oluşturulan kaynak bulunabilir. Ancak daha önce açıklanan nedenlerden dolayı, platform kodunda bu mekanizmanın 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 dolaylı etkileşimlerin sürdürülmesi zor olabilir. Paketin geri kalanıyla etkileşime geçmeniz gerçekten gerektiğinde her zaman makroları tercih edin.