Bu sayfada, oluşturulan kaynağın nasıl desteklendiği ve derleme sisteminde nasıl kullanılabileceği hakkında 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ı vardır: bindgen kullanarak C bağlamaları, AIDL arayüzleri ve protobuf arayüzleri oluşturma.
Oluşturulan kaynaktan gelen sandıklar
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ğı bir paket olarak kullanmaktır. include! makrosu oluşturulan kaynak için desteklenir ancak birincil amacı external/ içinde bulunan üçüncü taraf kodunu desteklemektir.
Platform kodu, include!() makrosu aracılığıyla oluşturulan kaynağı kullanmaya devam edebilir. Örneğin, genrule modülünü kullanarak benzersiz bir şekilde kaynak oluşturduğunuzda bu durum yaşanabilir.
Oluşturulan kaynağı dahil etmek için include!() makrosunu kullanın.
Oluşturulan kaynağı bir paket olarak kullanma, her bir modül sayfasındaki örneklerde açıklanmış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 örnek, 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ımına dayanmaktadır. Yapmadıysanız lütfen Defining a rust bindgen module (Rust bindgen modülü tanımlama) bölümüne gidin,
libbuzz_bindgen oluşturun ve ardından buraya geri dönün.
Bunun derleme dosyası bölümlerinin tüm kaynak oluşturucular için geçerli olduğunu unutmayın.
Oluşturulan kaynağı dahil etme 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 sandıklar?
C/C++ derleyicilerinin aksine, rustc yalnızca bir ikili veya kitaplığa giriş noktasını temsil eden tek bir kaynak dosyayı kabul eder. Kaynak ağacının, gerekli tüm kaynak dosyaların otomatik olarak bulunabileceği şekilde yapılandırılması beklenir. 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, build.rs komut dosyalarına ve Cargo derleme ortamıyla ilgili varsayımlara dayanarak bu farkla çalışır.
Derleme sırasında cargo komutu, OUT_DIR ortam değişkenini ayarlar. build.rs komut dosyalarının, oluşturulan kaynak kodu bu değişkene yerleştirmesi beklenir. Kaynak kodu eklemek için aşağıdaki komutu kullanın:
include!(concat!(env!("OUT_DIR"), "/hello.rs"));
Bu durum, her modülün çıkışları kendi out/dizinine1 yerleştirildiğinden Soong için bir zorluk teşkil eder. Bağımlılıkların oluşturulan kaynaklarını çıkardığı tek bir OUT_DIR yoktur.
Platform kodu için AOSP, oluşturulan kaynağın içe aktarılabilen bir pakete yerleştirilmesini tercih eder. Bunun çeşitli nedenleri vardır:
- Oluşturulan kaynak dosyası adlarının çakışmasını önleyin.
- Ağaç boyunca bakım gerektiren ortak metin kodları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 çevreleyen sandık arasında örtülü2 etkileşimlerden kaçının.
- En çok tercih edilen oluşturulmuş kaynakları dinamik olarak bağlayarak bellek ve disk üzerindeki baskıyı azaltın.
Sonuç olarak, Android'in tüm Rust kaynak oluşturma modülü türleri, derlenebilen ve crate olarak kullanılabilen kodlar üretir.
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 gibi durumlarda Soong, 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 mekanizmayı yalnızca kesinlikle gerekli olduğunda platform kodunda kullanmak en iyi uygulamadır.
-
Oluşturulan kaynağın yolu doğrudan derleyiciye sağlandığından bu durum C/C++ ve benzeri diller için herhangi bir sorun oluşturmaz. ↩
-
include!, metin dahil etme yoluyla çalıştığından kapsayan 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. Kasanın geri kalanıyla etkileşim gerçekten gerektiğinde her zaman makroları tercih edin. ↩