이 페이지는 생성된 소스가 지원되는 방법과 빌드 시스템에서 사용되는 방법에 대한 상위 수준 보기를 제공합니다.
모든 소스 생성기는 유사한 빌드 시스템 기능을 제공합니다. 세 가지 빌드 시스템 지원 소스 생성 사용 사례는 bindgen, AIDL 인터페이스 및 protobuf 인터페이스를 사용하여 C 바인딩을 생성하는 것입니다.
생성된 소스의 크레이트
소스 코드를 생성하는 모든 Rust 모듈은 마치 rust_library
로 정의된 것처럼 크레이트로 사용할 수 있습니다. (이는 이것이 rustlibs
, rlibs
및 dylibs
속성의 종속성으로 정의될 수 있음을 의미합니다.) 플랫폼 코드에 대한 최상의 사용 패턴은 생성된 소스를 크레이트로 사용하는 것입니다. include!
매크로는 생성된 소스에 대해 지원되며 주요 목적은 external/
에 있는 타사 코드를 지원하는 것입니다.
genrule
모듈을 사용하여 고유한 방식으로 소스를 생성하는 경우와 같이 플랫폼 코드가 include!()
매크로를 통해 생성된 소스를 계속 사용할 수 있는 경우가 있습니다.
include!()를 사용하여 생성된 소스 포함
생성된 소스를 크레이트로 사용하는 것은 각 특정(각) 모듈 페이지의 예제에서 다룹니다. 이 섹션에서는 include!()
매크로를 통해 생성된 소스를 참조하는 방법을 보여줍니다. 이 프로세스는 모든 소스 생성기에 대해 유사합니다.
전제 조건
이 예제는 rust_bindgen
모듈( libbuzz_bindgen
)을 정의했고 include!()
매크로를 사용하기 위해 생성된 소스를 포함하는 단계로 진행할 수 있다는 가정을 기반으로 합니다. 그렇지 않은 경우 Rust bindgen 모듈 정의 로 이동하여 libbuzz_bindgen
을 생성한 다음 여기로 돌아오십시오.
이것의 빌드 파일 부분은 모든 소스 생성기에 적용할 수 있습니다.
생성된 소스를 포함하는 단계
다음 내용으로 external/rust/hello_bindgen/Android.bp
를 만듭니다.
rust_binary {
name: "hello_bzip_bindgen_include",
srcs: [
// The primary rust source file must come first in this list.
"src/lib.rs",
// The module providing the bindgen bindings is
// included in srcs prepended by ":".
":libbuzz_bindgen",
],
// Dependencies need to be redeclared when generated source is used via srcs.
shared_libs: [
"libbuzz",
],
}
다음 내용으로 external/rust/hello_bindgen/src/bindings.rs
를 만듭니다.
#![allow(clippy::all)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused)]
#![allow(missing_docs)]
// Note that "bzip_bindings.rs" here must match the source_stem property from
// the rust_bindgen module.
include!(concat!(env!("OUT_DIR"), "/bzip_bindings.rs"));
다음 내용으로 external/rust/hello_bindgen/src/lib.rs
를 만듭니다.
mod bindings;
fn main() {
let mut x = bindings::foo { x: 2 };
unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}
생성된 소스를 위한 크레이트가 필요한 이유
C/C++ 컴파일러와 달리 rustc
는 바이너리 또는 라이브러리에 대한 진입점을 나타내는 단일 소스 파일만 허용합니다. 필요한 모든 소스 파일이 자동으로 검색될 수 있도록 소스 트리가 구성될 것으로 예상합니다. 이것은 생성된 소스가 소스 트리에 배치되거나 소스의 include 지시문을 통해 제공되어야 함을 의미합니다.
include!("/path/to/hello.rs");
Rust 커뮤니티는 이러한 차이점을 해결 하기 위해 build.rs
스크립트와 Cargo 빌드 환경에 대한 가정에 의존합니다. 빌드할 때, cargo
명령은 build.rs
스크립트가 생성된 소스 코드를 배치할 것으로 예상되는 OUT_DIR
환경 변수 를 설정합니다. 다음 명령을 사용하여 소스 코드를 포함합니다.
include!(concat!(env!("OUT_DIR"), "/hello.rs"));
이것은 각 모듈에 대한 출력이 고유 out/
디렉토리 1 에 배치되기 때문에 Soong에 대한 문제를 나타냅니다. 종속성이 생성된 소스를 출력하는 단일 OUT_DIR
이 없습니다.
플랫폼 코드의 경우 AOSP는 다음과 같은 몇 가지 이유로 인해 생성된 소스를 가져올 수 있는 상자에 패키징하는 것을 선호합니다.
- 생성된 소스 파일 이름이 충돌하지 않도록 합니다.
- 유지 관리가 필요한 트리 전체에 체크인된 상용구 코드를 줄입니다. 생성된 소스를 크레이트로 컴파일 하는 데 필요한 모든 상용구는 중앙에서 유지 관리할 수 있습니다.
- 생성된 코드와 주변 크레이트 간의 암시적 2 상호 작용을 피하십시오.
- 일반적으로 사용되는 생성 소스를 동적으로 연결하여 메모리와 디스크에 대한 부담을 줄입니다.
결과적으로 Android의 모든 Rust 소스 생성 모듈 유형은 컴파일 하여 크레이트로 사용할 수 있는 코드를 생성합니다. Soong은 모듈에 대해 생성된 모든 소스 종속성이 Cargo와 유사한 단일 모듈 디렉토리에 복사되는 경우 수정 없이 타사 크레이트를 계속 지원합니다. 이 경우 Soong은 모듈을 컴파일할 때 OUT_DIR
환경 변수를 해당 디렉터리로 설정하여 생성된 소스를 찾을 수 있도록 합니다. 그러나 이미 설명한 이유 때문에 절대적으로 필요한 경우에만 플랫폼 코드에서 이 메커니즘을 사용하는 것이 가장 좋습니다.