Yapı sistemi, rust_bindgen
modül türü aracılığıyla bağlama bağlamaları oluşturmayı destekler. Bindgen, C kitaplıklarına Rust FFI bağlamaları sağlar ( cppstd
özelliğinin ayarlanmasını gerektiren bazı sınırlı C++ desteğiyle).
Temel Rust_bindgen kullanımı
Aşağıda, bağlayıcı kullanan bir modülün nasıl tanımlanacağına ve bu modülün kasa olarak nasıl kullanılacağına dair bir örnek yer almaktadır. Harici kod gibi bir include!()
makrosu aracılığıyla bağlama bağlamaları kullanmanız gerekiyorsa, Kaynak Oluşturucular sayfasına bakın.
Rust'tan çağrılacak örnek C kütüphanesi
Rust'ta kullanılacak bir yapı ve işlevi tanımlayan örnek bir C kütüphanesi aşağıdadır.
external/rust/libbuzz/libbuzz.h
typedef struct foo {
int x;
} foo;
void fizz(int i, foo* cs);
external/rust/libbuzz/libbuzz.c
#include <stdio.h>
#include "libbuzz.h"
void fizz(int i, foo* my_foo){
printf("hello from c! i = %i, my_foo->x = %i\n", i, my_foo->x);
}
Bir Rust_bindgen modülü tanımlayın
İlgili tüm başlıkları içeren external/rust/libbuzz/libbuzz_wrapper.h
bir sarmalayıcı başlığı tanımlayın:
// Include headers that are required for generating bindings in a wrapper header.
#include "libbuzz.h"
Android.bp
dosyasını external/rust/libbuzz/Android.bp
olarak tanımlayın:
cc_library {
name: "libbuzz",
srcs: ["libbuzz.c"],
}
rust_bindgen {
name: "libbuzz_bindgen",
// Crate name that's used to generate the rust_library variants.
crate_name: "buzz_bindgen",
// Path to the wrapper source file.
wrapper_src: "libbuzz_wrapper.h",
// 'source_stem' controls the output filename.
// This is the filename that's used in an include! macro.
//
// In this case, we just use "bindings", which produces
// "bindings.rs".
source_stem: "bindings",
// Bindgen-specific flags and options to customize the bindings.
// See the bindgen manual for more information.
bindgen_flags: ["--verbose"],
// Clang flags to be used when generating the bindings.
cflags: ["-DSOME_FLAG"],
// Shared, static, and header libraries which export the necessary
// include directories must be specified.
//
// These libraries will also be included in the crate if static,
// or propagated to dependents if shared.
// static_libs: ["libbuzz"]
// header_libs: ["libbuzz"]
shared_libs: ["libbuzz"],
}
Bağlama bayraklarını kullanma hakkında daha fazla bilgi edinmek için Oluşturulan Bağlamaları Özelleştirme konusundaki bağlama kılavuzu bölümüne bakın.
Bu bölümü include!()
makrosunu kullanmanın ön koşulu olarak bir rust_bindgen
modülünü tanımlamak için kullandıysanız, Kaynak Oluşturucular sayfasında Önkoşul'a dönün. Değilse sonraki bölümlere geçin.
Bağlamaları sandık olarak kullanın
Aşağıdaki içerikle external/rust/hello_bindgen/Android.bp
oluşturun:
rust_binary {
name: "hello_bindgen",
srcs: ["main.rs"],
// Add the rust_bindgen module as if it were a rust_library dependency.
rustlibs: ["libbuzz_bindgen"],
}
Aşağıdaki içerikle external/rust/hello_bindgen/src/main.rs
oluşturun:
//! Example crate for testing bindgen bindings
fn main() {
let mut x = buzz_bindgen::foo { x: 2 };
unsafe { buzz_bindgen::fizz(1, &mut x as *mut buzz_bindgen::foo) }
}
Son olarak ikili dosyayı oluşturmak için m hello_bindgen
çağırın.
Bindgen bağlamalarını test edin
Bindgen bağlamaları genellikle bellek düzeni uyumsuzluklarını önlemek için bir dizi oluşturulmuş düzen testi içerir. AOSP, bu testler için tanımlanmış bir test modülüne sahip olmanızı ve testlerin projenizin normal test paketinin bir parçası olarak çalıştırılmasını önerir.
Bunlar için bir test ikili dosyası external/rust/hello_bindgen/Android.bp
dosyasında bir rust_test
modülü tanımlanarak kolayca üretilebilir:
rust_test {
name: "bindings_test",
srcs: [
":libbuzz_bindgen",
],
crate_name: "buzz_bindings_test",
test_suites: ["general-tests"],
auto_gen_config: true,
// Be sure to disable lints as the generated source
// is not guaranteed to be lint-free.
clippy_lints: "none",
lints: "none",
}
Görünürlük ve bağlantı
Tür tanımları, işlev imzaları ve ilgili sabitlerden oluştuğu için oluşturulan bağlamalar genellikle çok küçüktür. Sonuç olarak, bu kütüphaneleri dinamik olarak birbirine bağlamak genellikle israftır. Bu modüller için dinamik bağlantıyı devre dışı bıraktık, böylece bunları rustlibs
aracılığıyla kullanmak otomatik olarak statik bir değişken seçecektir.
Varsayılan olarak, rust_bindgen
modülleri [":__subpackages__"]
visibility
özelliğine sahiptir; bu, yalnızca aynı Android.bp
dosyasındaki veya dizin hiyerarşisinde onun altındaki modüllerin onu görmesine izin verir. Bu iki amaca hizmet eder:
- Ağacın başka yerlerinde ham C bağlamalarının kullanılmasını engeller.
- Statik ve dinamik bağlantının bir karışımıyla elmas bağlantı sorunlarını önler.
Genellikle, diğer geliştiricilerin kullanması amaçlanan bağlamalarla aynı dizin ağacına eklediğiniz oluşturulan modülün etrafına güvenli bir sarmalayıcı kitaplığı sağlamanız gerekir. Bu, kullanım durumunuz için işe yaramazsa görünürlüğe ek paketler ekleyebilirsiniz. Ek görünürlük kapsamları eklerken lütfen gelecekte aynı sürece bağlanabilecek iki kapsamı eklememeye dikkat edin; aksi takdirde bağlantı kurulamaz.
Dikkate değer Rust_bindgen özellikleri
Aşağıda tanımlanan özellikler, tüm modüller için geçerli olan Önemli ortak özelliklere ek olarak verilmiştir. Bunlar ya Rust bağlama modülleri için özellikle önemlidir ya da rust_bindgen
modül tipine özgü benzersiz davranışlar sergiler.
kök, ad, sandık_adı
rust_bindgen
kitaplık değişkenleri ürettiğinden, stem
, name
ve crate_name
özellikleri için rust_library
modülleriyle aynı gereksinimleri paylaşırlar. Referans için Önemli Rust kitaplığı özelliklerine bakın.
sarmalayıcı_src
Bu, bu bağlamalar için gereken başlıkları içeren sarmalayıcı başlık dosyasının göreceli yoludur. Dosya uzantısı, başlığın nasıl yorumlanacağını ve varsayılan olarak hangi -std
bayrağının kullanılacağını belirler. Uzantı .hh
veya .hpp
olmadığı sürece bunun bir C başlığı olduğu varsayılır. C++ başlığınızın başka bir uzantıya sahip olması gerekiyorsa cpp_std
özelliğini, dosyanın bir C dosyası olduğunu varsayan varsayılan davranışı geçersiz kılacak şekilde ayarlayın.
kaynak_stem
Bu , oluşturulan kaynak dosyanın dosya adıdır. Bağlamaları bir kasa olarak kullanıyor olsanız bile bu alanın tanımlanması gerekir , çünkü stem
özelliği yalnızca oluşturulan kitaplık varyantları için çıktı dosya adını kontrol eder. Bir modül, rustlibs
aracılığıyla kasalar yerine kaynak olarak birden fazla kaynak oluşturucuya ( bindgen
ve protobuf
gibi) bağlıysa, o modülün bağımlılığı olan tüm kaynak oluşturucuların benzersiz source_stem
değerlerine sahip olduğundan emin olmalısınız. Bağımlı modüller, srcs
tanımlanan tüm SourceProvider
bağımlılıklarından kaynakları ortak bir OUT_DIR
dizinine kopyalar; böylece source_stem
çarpışmalar, OUT_DIR
dizininde oluşturulan kaynak dosyalarının üzerine yazılmasına neden olur.
c_std
Bu, hangi C standardı sürümünün kullanılacağını temsil eden bir dizedir. Geçerli değerler aşağıda listelenmiştir:
-
"gnu11"
gibi belirli bir sürüm. -
build/soong/cc/config/global.go
dosyasında derleme sistemi tarafından tanımlanan bir değer olan"experimental"
, kullanılabilir olduklarında C++1z gibi taslak sürümleri kullanabilir. - Unset veya
""
, derleme sistemi varsayılanının kullanılması gerektiğini belirtir.
Bu ayarlanırsa dosya uzantısı göz ardı edilir ve başlığın bir C başlığı olduğu varsayılır. Bu cpp_std
ile aynı anda ayarlanamaz.
cpp_std
cpp_std
hangi C standart sürümünün kullanılacağını temsil eden bir dizedir. Geçerli değerler:
-
"gnu++11"
gibi belirli bir sürüm -
build/soong/cc/config/global.go
dosyasında derleme sistemi tarafından tanımlanan bir değer olan"experimental"
, kullanılabilir olduklarında C++1z gibi taslak sürümleri kullanabilir. - Unset veya
""
, derleme sistemi varsayılanının kullanılması gerektiğini belirtir.
Bu ayarlanırsa dosya uzantısı göz ardı edilir ve başlığın bir C++ başlığı olduğu varsayılır. Bu c_std
ile aynı anda ayarlanamaz.
bayraklar
cflags
başlıkları doğru şekilde yorumlamak için gereken Clang bayraklarının bir dize listesini sağlar.
özel_bindgen
Gelişmiş kullanım örnekleri için, Bingen, özel bir Rust ikili dosyasının parçası olarak işlenebilen bir API sağlayarak bir kitaplık olarak kullanılabilir. custom_bindgen
alanı, normal bindgen
ikili dosyası yerine bingen API'sini kullanan bir rust_binary_host
modülünün modül adını alır.
Bu özel ikili dosyanın, bindgen
benzer şekilde bağımsız değişkenler beklemesi gerekir; örneğin
$ my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]
Bunların çoğu, bindgen
kütüphanesinin kendisi tarafından işlenir. Bu kullanımın bir örneğini görmek için external/rust/crates/libsqlite3-sys/android/build.rs adresini ziyaret edin.
Ek olarak, kütüphanenin derlenmesini kontrol etmek için kütüphane özelliklerinin tam seti mevcuttur, ancak bunların nadiren tanımlanmasına veya değiştirilmesine ihtiyaç vardır.