Derleme sistemi, rust_bindgen
modül türü aracılığıyla bindgen bağlamalarını oluşturmayı destekler. Bindgen, C kitaplıklarına Rust FFI bağlantıları sağlar (ancak bazı
cppstd
özelliğinin ayarlanmasını gerektiren sınırlı C++ desteği).
rust_bindgen'in temel kullanımı
Aşağıda, bindgen ve
ve kafes olarak nasıl kullanacağınızı göstereceğim.
include!()
makrosu için
Kaynak Oluşturucular
sayfasını ziyaret edin.
Rust'tan çağrı yapmak için örnek C kitaplığı
Aşağıda, Rust'ta kullanılmak üzere bir yapı ve işlev tanımlayan örnek bir C kitaplığı verilmiştir.
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);
}
rust_bindgen modülü tanımlama
Şunları içeren bir sarmalayıcı başlığı (external/rust/libbuzz/libbuzz_wrapper.h
) tanımlayın
başlıkları ekleyin:
// 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"],
}
Bindgen flag'lerini kullanma hakkında daha fazla bilgi için bindgen manuel bölümüne bakın. Oluşturulan Bağlamaları Özelleştirme hakkında daha fazla bilgi edinin.
Bu bölümü kullanarak bir rust_bindgen
modülü tanımlamak için kullanılan
include!()
makrosu ile Ön koşul'a dönün.
hakkındaki makalemizi incelemenizi öneririz. Aksi takdirde sonraki bölümlere geçin.
Bağlamaları kafes 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
işlevini çağırın.
Bindgen bağlamalarını test etme
Bindgen bağlamaları genellikle eşleşmez. AOSP, bu testler için tanımlanmış bir test modülünüzün olmasını ve testlerin projenizin normal test paketi kapsamında çalıştırılmasını önerir.
Bunlar için bir test ikili dosyası, external/rust/hello_bindgen/Android.bp
içinde 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ı
Oluşturulan bağlamalar, tür tanımlarından, işlev imzalarından ve ilgili sabitlerden oluştuğu için genellikle çok küçüktür. Bu nedenle, bu kitaplıkları dinamik olarak bağlamak genellikle gereksizdir. Bu modülleri rustlibs
üzerinden kullanırken otomatik olarak statik bir varyantın seçilmesi için dinamik bağlantıyı devre dışı bıraktık.
rust_bindgen
modül, varsayılan olarak şu visibility
özelliğine sahiptir:
[":__subpackages__"]
(Yalnızca aynı Android.bp
öğesindeki modüllere izin verilir)
dizin hiyerarşisinde bulunduğunu varsayalım. Bu işlem iki amaca hizmet eder:
- Ham C bağlamalarının ağacın başka bir yerinde kullanılmasını engeller.
- Statik ve dinamik bağlantıların bir karışımıyla elmas bağlantı sorunlarını önler.
Genellikle, oluşturulan modülün etrafında güvenli bir sarmalayıcı kitaplığı sağlamanız gerekir için amaçlanan bağlamalarla aynı dizin ağacına eklediğiniz diğer geliştiricilerden de yararlanabilirsiniz. Bu, kullanım alanınız için uygun değilse görünürlük için başka paketler ekleyebilirsiniz. Başka görünürlük kapsamları eklerken lütfen şunları eklememeye dikkat edin: gelecekte aynı sürece bağlanabilecek iki kapsam, bağlantı kurulamadı.
Önemli rust_bindgen özellikleri
Aşağıda tanımlanan özellikler, Önemli yaygın özelliklere ek olarak kullanılır.
geçerli olacak iki yöntem vardır. Bunlar Rust için özellikle önemli.
bağlamayabilir veya rust_bindgen
modül türüne özgü benzersiz davranış sergileyebilir.
kök, ad, sandık_adı
rust_bindgen
kitaplık varyantları oluşturduğundan stem
, name
ve crate_name
mülkleri için rust_library
modülleriyle aynı koşulları paylaşır. Görüntüleyin
Önemli Rust kitaplığı özellikleri
referans olarak kullanabilirsiniz.
sarmalayıcı_src
Bu, bu bağlamalar için gereken üstbilgileri içeren bir sarmalayıcı üstbilgi dosyasının göreli yoludur. Dosya uzantısı, üstbilginin nasıl yorumlanacağını ve varsayılan olarak hangi -std
işaretinin kullanılacağını belirler. Uzantısı .hh
veya .hpp
olmadığı sürece bunun bir C başlığı olduğu varsayılır. C++ başlığınızda
başka bir uzantı varsa cpp_std
özelliğini, varsayılan davranışı geçersiz kılacak şekilde ayarlayın
bir C dosyası oluşturun.
source_stem
Bu, oluşturulan kaynak dosyanın dosya adıdır. stem
mülkü yalnızca oluşturulan kitaplık varyantlarının çıkış dosya adını kontrol ettiğinden, bağlamaları paket olarak kullanıyor olsanız bile bu alan tanımlanmalıdır.
Bir modül birden fazla kaynak oluşturucuya bağlıysa (bindgen
ve protobuf
gibi)
kaynak olarak sağlamanız gerekiyorsa, tüm kaynak derleyicilerin rustlibs
bu modülün bağımlılıkları benzersiz source_stem
değerlerine sahiptir. Bağımlı modüller
tanımlanan SourceProvider
bağımlılığın tümünün kaynaklarını kopyala
srcs
ile ortak bir OUT_DIR
dizini arasında bağlantı kurar. Dolayısıyla source_stem
içerisindeki çakışmalar
oluşturulan kaynak dosyaların OUT_DIR
dizininde üzerine yazılmasına neden olur.
c_std
Bu, kullanılacak C standardı sürümünü temsil eden bir dizedir. Geçerli değerler aşağıdaki listede yer almaktadır:
"gnu11"
gibi belirli bir sürüm."experimental"
(Bu,build/soong/cc/config/global.go
kullanabilir C++1z gibi taslak sürümler yeniden kullanılabilir.- Ayarlanmamış veya
""
(derleme sistemi varsayılanının kullanılacağını belirtir).
Bu ayarlanırsa dosya uzantısı yoksayılır ve başlığın
C üstbilgisi olmalıdır. Bu, cpp_std
ile aynı anda ayarlanamaz.
cpp_std
cpp_std
, kullanılacak C standart sürümünü temsil eden bir dizedir. Geçerli değerler:
"gnu++11"
gibi belirli bir sürüm"experimental"
; bu, derleme sistemi tarafındanbuild/soong/cc/config/global.go
kullanabilir C++1z gibi taslak sürümler yeniden kullanılabilir.- Ayarlanmadı veya derleme sisteminin varsayılan değerinin kullanılması gerektiğini belirten
""
.
Bu ayarlanırsa dosya uzantısı yoksayılır ve başlığın
C++ üstbilgisi olmalıdır. Bu, c_std
ile aynı anda ayarlanamaz.
kamuflajlar
cflags
,
konu başlıklarına bakabilir.
custom_bindgen
Gelişmiş kullanım alanları için bindgen, kitaplık olarak kullanılabilir. Bu kitaplık, özel bir Rust ikili dosyası kapsamında değiştirilebilecek bir API sağlar. custom_bindgen
alanı, normal bindgen
ikili dosyası yerine bindgen API'yi kullanan bir rust_binary_host
modülünün modül adını alır.
Bu özel ikili, bindgen
'e benzer şekilde bağımsız değişkenler beklemelidir. Örneğin:
$ my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]
Bunların çoğu bindgen
kitaplığı tarafından yönetilir. Bu kullanıma dair bir örnek görmek için external/rust/crates/libsqlite3-sys/android/build.rs adresini ziyaret edin.
Ayrıca, kitaplığın derlenmesini kontrol etmek için kitaplık özelliklerinin tamamı kullanılabilir. Ancak bu özelliklerin nadiren tanımlanması veya değiştirilmesi gerekir.
handle_static_inline ve static_inline_library
Bu iki mülkün birlikte kullanılması amaçlanmıştır ve bunların üretilmesine olanak sağlar. dışa aktarılan bağlamanın en iyi yolu vardır.
Bunları kullanmak için handle_static_inline: true
politikasını ve static_inline_library
değerini şu şekilde ayarlayın:
rust_bindgen
modülünü şu şekilde tanımlayan karşılık gelen bir cc_library_static
:
kaynak girişine dokunun.
Örnek kullanım:
rust_bindgen {
name: "libbindgen",
wrapper_src: "src/any.h",
crate_name: "bindgen",
stem: "libbindgen",
source_stem: "bindings",
// Produce bindings for static inline fucntions
handle_static_inline: true,
static_inline_library: "libbindgen_staticfns"
}
cc_library_static {
name: "libbindgen_staticfns",
// This is the rust_bindgen module defined above
srcs: [":libbindgen"],
// The include path to the header file in the generated c file is
// relative to build top.
include_dirs: ["."],
}