ビルドシステムは、 rust_bindgen
モジュールタイプを介したbindgenバインディングの生成をサポートします。 Bindgenは、CライブラリへのRust FFIバインディングを提供します(一部の制限されたC ++サポートでは、 cppstd
プロパティの設定が必要です)。
基本的なrust_bindgenの使用法
以下は、bindgenを使用するモジュールを定義する方法と、そのモジュールをクレートとして使用する方法の例です。外部コードなど、 include!()
マクロを介してbindgenバインディングを使用する必要がある場合は、ソースジェネレータのページを参照してください。
Rustから呼び出すCライブラリの例
Rustで使用する構造体と関数を定義するCライブラリの例を次に示します。
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モジュールの定義
ラッパーヘッダー、 external/rust/libbuzz/libbuzz_wrapper.h
を定義します。これには、関連するすべてのヘッダーが含まれます。
// Include headers that are required for generating bindings in a wrapper header.
#include "libbuzz.h"
Android.bp
ファイルをexternal/rust/libbuzz/Android.bp
として定義します。
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フラグの使用の詳細については、生成されたバインディングのカスタマイズに関するbindgenのマニュアルセクションを参照してください。
このセクションを使用して、 include!()
マクロを使用するための前提条件としてrust_bindgen
モジュールを定義した場合は、[ソースジェネレーター]ページの[前提条件]に戻ります。そうでない場合は、次のセクションに進みます。
ビンディングを木枠として使用する
次のコンテンツを使用してexternal/rust/hello_bindgen/Android.bp
を作成します。
rust_binary {
name: "hello_bindgen",
srcs: ["main.rs"],
// Add the rust_bindgen module as if it were a rust_library dependency.
rustlibs: ["libbuzz_bindgen"],
}
次の内容でexternal/rust/hello_bindgen/src/main.rs
を作成します。
//! 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) }
}
最後に、 m hello_bindgen
を呼び出してバイナリをビルドします。
Bindgenバインディングのテスト
Bindgenバインディングには通常、メモリレイアウトの不一致を防ぐために、生成された多数のレイアウトテストが含まれています。 AOSPでは、これらのテスト用にテストモジュールを定義し、プロジェクトの通常のテストスイートの一部としてテストを実行することをお勧めします。
これらのテストバイナリは、 external/rust/hello_bindgen/Android.bp
でrust_test
モジュールを定義することで簡単に作成できます:
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",
}
注目すべきrust_bindgenプロパティ
以下に定義されているプロパティは、すべてのモジュールに適用される重要な共通プロパティに追加されます。これらは、Rust bindgenモジュールにとって特に重要であるか、 rust_bindgen
モジュールタイプに固有の固有の動作を示します。
ステム、名前、crate_name
rust_bindgen
はライブラリバリアントを生成するため、 stem
、 name
、およびcrate_name
プロパティのrust_library
モジュールと同じ要件を共有します。参考のために、注目すべきRustライブラリのプロパティを参照してください。
wrapper_src
これは、これらのバインディングに必要なヘッダーを含むラッパーヘッダーファイルへの相対パスです。ファイル拡張子は、ヘッダーの解釈方法を決定し、デフォルトで使用する-std
フラグを決定します。拡張子が.hh
または.hpp
でない限り、これはCヘッダーであると見なされます。 C ++ヘッダーに他の拡張子が必要な場合は、 cpp_std
プロパティを設定して、ファイルがCファイルであると想定するデフォルトの動作をオーバーライドします。
source_stem
これは、生成されたソースファイルのファイル名です。バインディングをクレートとして使用している場合でも、 stem
プロパティは生成されたライブラリバリアントの出力ファイル名のみを制御するため、このフィールドを定義する必要があります。モジュールがrustlibs
を介したクレートとしてではなく、ソースとして複数のソースジェネレーター( bindgen
やprotobuf
など)に依存している場合、そのモジュールの依存関係であるすべてのソースジェネレーターが一意のsource_stem
値を持っていることを確認する必要があります。依存モジュールは、 srcs
で定義されているすべてのSourceProvider
依存関係から共通のOUT_DIR
ディレクトリにソースをコピーするため、 source_stem
での衝突により、生成されたソースファイルがOUT_DIR
ディレクトリで上書きされます。
c_std
これは、使用するC標準バージョンを表す文字列です。有効な値は次のとおりです。
- 「gnu11」などの特定のバージョン
build/soong/cc/config/global.go
のビルドシステムによって定義された「実験的」値は、利用可能な場合、 C++1zなどのドラフトバージョンを使用する場合があります。- 「デフォルト」または「」はどちらもビルドシステムのデフォルトを使用します。
これが設定されている場合、ファイル拡張子は無視され、ヘッダーはCヘッダーであると見なされます。 cpp_std
と同時に設定することはできません。
cpp_std
cpp_std
は、使用するC標準バージョンを表す文字列です。有効な値:
「gnu++11」などの特定のバージョン
build/soong/cc/config/global.go
のビルドシステムによって定義された「実験的」値は、利用可能な場合、 C++1zなどのドラフトバージョンを使用する場合があります。- 「デフォルト」または「」両方のビルドシステムのデフォルト。
これが設定されている場合、ファイル拡張子は無視され、ヘッダーはC++ヘッダーであると見なされます。 c_std
と同時に設定することはできません。
cflags
cflags
は、ヘッダーを正しく解釈するために必要なClangフラグの文字列リストを提供します。
custom_bindgen
高度なユースケースでは、bindgenをライブラリとして使用して、カスタムRustバイナリの一部として操作できるAPIを提供できます。 custom_bindgen
フィールドは、通常のbindgen
バイナリの代わりにbindgenAPIを使用するrust_binary_host
モジュールのモジュール名を取ります。
このカスタムバイナリは、「 my_bindgen [flags] wrapper_header.h -o [output\_path] -- [clang flags]
」などのbindgen
と同様の方法で引数を期待する必要があります。これのほとんどは、 bindgen
ライブラリ自体によって処理されます。この使用例を確認するには、 external / rust / crates / libsqlite3-sys / android/build.rsにアクセスしてください。
さらに、ライブラリのコンパイルを制御するためにライブラリプロパティのフルセットを使用できますが、これらを定義または変更する必要はほとんどありません。