Bindgenバインディングモジュール

ビルドシステムは、 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.bprust_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はライブラリバリアントを生成するため、 stemname 、およびcrate_nameプロパティのrust_libraryモジュールと同じ要件を共有します。参考のために、注目すべきRustライブラリのプロパティを参照してください。

wrapper_src

これは、これらのバインディングに必要なヘッダーを含むラッパーヘッダーファイルへの相対パスです。ファイル拡張子は、ヘッダーの解釈方法を決定し、デフォルトで使用する-stdフラグを決定します。拡張子が.hhまたは.hppない限り、これはCヘッダーであると見なされます。 C ++ヘッダーに他の拡張子が必要な場合は、 cpp_stdプロパティを設定して、ファイルがCファイルであると想定するデフォルトの動作をオーバーライドします。

source_stem

これは、生成されたソースファイルのファイル名です。バインディングをクレートとして使用している場合でも、 stemプロパティは生成されたライブラリバリアントの出力ファイル名のみを制御するため、このフィールドを定義する必要があります。モジュールがrustlibsを介したクレートとしてではなく、ソースとして複数のソースジェネレーター( bindgenprotobufなど)に依存している場合、そのモジュールの依存関係であるすべてのソースジェネレーターが一意の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にアクセスしてください

さらに、ライブラリのコンパイルを制御するためにライブラリプロパティのフルセットを使用できますが、これらを定義または変更する必要はほとんどありません。