Bindgen 바인딩 모듈

빌드 시스템은 rust_bindgen 모듈 유형을 통해 bindgen 바인딩 생성을 지원합니다. Bindgen은 C 라이브러리에 대한 Rust FFI 바인딩을 제공합니다( cppstd 속성 설정이 필요한 일부 제한된 C++ 지원 포함).

기본 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 매뉴얼 섹션을 참조하십시오.

이 섹션을 사용하여 rust_bindgen 모듈을 include!() 매크로를 사용하기 위한 전제 조건으로 정의했다면 소스 생성기 페이지의 전제 조건 으로 돌아가십시오. 그렇지 않은 경우 다음 섹션을 진행합니다.

바인딩을 크레이트로 사용

다음 콘텐츠로 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 은 라이브러리 변형을 생성하므로 stem , namecrate_name 속성에 대해 rust_library 모듈과 동일한 요구 사항을 공유합니다. 참조용으로 주목할만한 Rust 라이브러리 속성 을 참조하세요.

래퍼_src

이것은 이러한 바인딩에 필요한 헤더를 포함하는 래퍼 헤더 파일에 대한 상대 경로입니다. 파일 확장자는 헤더를 해석하는 방법을 결정하고 기본적으로 사용할 -std 플래그를 결정합니다. 확장자가 .hh 또는 .hpp아니면 C 헤더로 간주됩니다. C++ 헤더에 다른 확장자가 있어야 하는 경우 파일이 C 파일이라고 가정하는 기본 동작을 재정의하도록 cpp_std 속성을 설정합니다.

소스_줄기

이것은 생성된 소스 파일 의 파일 이름입니다. 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와 같은 초안 버전 을 사용할 수 있습니다.
    • "default" 또는 " " 둘 다 빌드 시스템 기본값을 사용합니다.

이것이 설정되면 파일 확장자는 무시되고 헤더는 C 헤더로 간주됩니다. 이것은 cpp_std 와 동시에 설정할 수 없습니다.

cpp_std

cpp_std 는 사용할 C 표준 버전을 나타내는 문자열입니다. 유효한 값:

  • "gnu++11"과 같은 특정 버전

    • build/soong/cc/config/global.go 의 빌드 시스템에 의해 정의된 "실험적" 값은 사용 가능한 경우 C++1z와 같은 초안 버전 을 사용할 수 있습니다.
    • "default" 또는 " " 모두 빌드 시스템 기본값입니다.

이것이 설정되면 파일 확장자는 무시되고 헤더는 C++ 헤더로 간주됩니다. 이것은 c_std 와 동시에 설정할 수 없습니다.

cflags

cflags 는 헤더를 올바르게 해석하는 데 필요한 Clang 플래그의 문자열 목록을 제공합니다.

custom_bindgen

고급 사용 사례의 경우 bindgen을 라이브러리로 사용하여 사용자 정의 Rust 바이너리의 일부로 조작할 수 있는 API를 제공할 수 있습니다. custom_bindgen 필드는 일반 bindgen 바이너리 대신 bindgen API를 사용하는 rust_binary_host 모듈의 모듈 이름을 사용합니다.

이 사용자 정의 바이너리는 " my_bindgen [flags] wrapper_header.h -o [output\_path] -- [clang flags] "와 같이 bindgen 과 유사한 방식으로 인수를 예상해야 합니다. 이 대부분은 bindgen 라이브러리 자체에서 처리됩니다. 이 사용법의 예를 보려면 external/rust/crates/libsqlite3-sys/android/build.rs 를 방문하십시오.

또한 정의하거나 변경할 필요가 거의 없지만 전체 라이브러리 속성 집합을 사용하여 라이브러리 컴파일을 제어할 수 있습니다.