本頁面概略說明系統如何支援產生的來源,以及如何在建構系統中使用。
所有來源產生器都提供類似的建構系統功能。系統支援三個建構系統支援的來源產生用途,分別使用 bindgen、AIDL 介面和 protobuf 介面產生 C 繫結。
產生來源的 Crate
每個產生來源程式的 Rust 模組都可以用作 Crate,就像是定義為 rust_library
一樣。(這表示該變數可在 rustlibs
、rlibs
和 dylibs
屬性中定義為依附元件)。平台程式碼的最佳使用模式,就是使用產生的來源做為 Crate。雖然產生的來源支援 include!
巨集,但其主要用途是支援位於 external/
中的第三方程式碼。
在某些情況下,平台程式碼可能會透過 include!()
巨集使用產生的來源,例如當您使用 genrule
模組以獨特方式產生來源時。
使用 include!() 納入產生的來源
每個特定 (相對應) 模組頁面中的範例都會說明如何使用產生的來源做為 Crate。本節說明如何透過 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) }
}
為何要為產生的來源建立 Crate
與 C/C++ 編譯器不同,rustc
只接受單一來源檔案,代表二進位檔或程式庫的進入點。它會預期來源樹狀結構的架構,以便自動探索所有必要的來源檔案。這表示產生的來源必須放置在來源樹狀結構中,或透過來源中的 include 指令提供:
include!("/path/to/hello.rs");
Rust 社群會依賴 build.rs
指令碼,並假設 Cargo 建構環境可處理此差異。建構時,cargo
指令會設定 OUT_DIR
環境變數,build.rs
指令碼會將產生的原始碼放入其中。請使用下列指令加入原始碼:
include!(concat!(env!("OUT_DIR"), "/hello.rs"));
這會對 Soong 造成挑戰,因為每個模組的輸出內容都會放在各自的 out/
目錄中1。沒有任何 OUT_DIR
會輸出依附元件產生的來源。
針對平台程式碼,Android 開放原始碼計畫會優先將產生的來源封裝至可匯入的 Crate,原因如下:
- 避免產生的來源檔案名稱發生衝突。
- 減少需要維護的樹狀結構中檢入的樣板程式碼。任何用於將產生的來源編譯至 Crate 的樣板,都可以集中維護。
- 避免產生程式碼與周圍 Crate 之間的隱含2 互動。
- 透過動態連結常用的產生來源,減少記憶體和磁碟的壓力。
因此,所有 Android 的 Rust 來源產生模組類型都會產生可編譯並用於crate 的程式碼。如果在與 Cargo 類似的情況下,將模組產生的所有來源依附元件複製到單一的個別模組目錄,Soong 仍支援第三方 Crate,且無須進行修改。在這種情況下,Soong 會在編譯模組時將 OUT_DIR
環境變數設為該目錄,以便找到已產生的來源。不過,基於上述原因,建議您只在必要時才在平台程式碼中使用此機制。