Moduli Rust per Android

Come principio generale, le definizioni dei moduli rust_* si attengono strettamente all'utilizzo e alle aspettative di cc_*. Di seguito è riportato un esempio di definizione di modulo per un file binario Rust:

rust_binary {
    name: "hello_rust",
    crate_name: "hello_rust",
    srcs: ["src/hello_rust.rs"],
    host_supported: true,
}

Questa pagina illustra le proprietà più comuni per i moduli rust_*. Per saperne di più su tipi di moduli specifici e definizioni di moduli di esempio, consulta Moduli binari, Moduli della libreria o Moduli di test.

Tipi di moduli di base

TipoDefinizionePer ulteriori informazioni
rust_binaryUn file binario Rust Pagina Moduli binari
rust_libraryProduce una libreria Rust e fornisce sia le varianti rlib sia quelle dylib. rust_library, pagina Moduli della raccolta.
rust_ffiProduce una libreria C Rust utilizzabile dai moduli cc e fornisce varianti sia statiche che condivise. rust_ffi, pagina Moduli della raccolta
rust_proc_macroProduce una libreria proc-macro Rust. (Sono analoghi ai plug-in del compilatore). rust_proc_macro, pagina Moduli librerie
rust_testProduce un file binario di test Rust che utilizza il test harness Rust standard. Pagina Testa i moduli
rust_fuzzProduce un file binario di fuzz Rust che sfrutta libfuzzer. Esempio di modulo rust_fuzz
rust_protobufGenera il codice sorgente e produce una libreria Rust che fornisce un'interfaccia per un determinato protobuf. Pagine Moduli Protobuf e Generatori di codice
rust_bindgenGenera il codice sorgente e produce una libreria Rust contenente le associazioni Rust alle librerie C. Moduli di associazioni Bindgen e pagine Generatori di codice sorgente

Proprietà comuni importanti

Queste proprietà sono comuni a tutti i moduli Rust per Android. Eventuali proprietà aggiuntive (uniche) associate ai singoli moduli Rust sono elencate nella pagina del modulo.

nome

name è il nome del modulo. Come per gli altri moduli Soong, deve essere univoco nella maggior parte dei tipi di moduli Android.bp. Per impostazione predefinita, name viene utilizzato come nome del file di output. Se il nome file di output deve essere diverso dal nome del modulo, utilizza la proprietà stem per definirlo.

gambo

stem (facoltativo) consente di controllare direttamente il nome del file di output (esclusa l'estensione del file e altri suffissi). Ad esempio, una raccolta rust_library_rlib con un valore del tronco pari a libfoo produce un file libfoo.rlib. Se non fornisci un valore per la proprietà stem, il nome del file di output adotta per impostazione predefinita il nome del modulo.

Utilizza la funzione stem quando non riesci a impostare il nome del modulo sul nome file di output desiderato. Ad esempio, il rust_library per il contenitore log è denominato liblog_rust, perché esiste già un liblog cc_library. In questo caso, l'utilizzo della proprietà stem garantisce che il file di output sia denominato liblog.* anziché liblog_rust.*.

src

srcs contiene un singolo file di origine che rappresenta il punto di contatto del modulo (di solito main.rs o lib.rs). rustc gestisce la risoluzione e il rilevamento di tutti gli altri file di origine necessari per la compilazione, che vengono enumerati nel file deps prodotto.

Se possibile, evita questo utilizzo per il codice della piattaforma. Per ulteriori informazioni, consulta Generatori di codice sorgente.

crate_name

crate_name imposta i metadati del nome della cassetta tramite il flag rustc --crate_name. Per i moduli che producono librerie, questo deve corrispondere al nome della cassetta previsto utilizzato nel codice sorgente. Ad esempio, se al modulo libfoo_bar viene fatto riferimento in source come extern crate foo_bar, questo deve essere crate_name: "foo_bar".

Questa proprietà è comune a tutti i moduli rust_*, ma è obbligatoria per i moduli che producono librerie Rust (ad esempio rust_library rust_ffi, rust_bindgen, rust_protobuf e rust_proc_macro). Questi moduli applicano i requisiti rustc alla relazione tra crate_name e il nome file di output. Per ulteriori informazioni, consulta la sezione Moduli della libreria.

lint

Il linting rustc viene eseguito per impostazione predefinita per tutti i tipi di moduli, ad eccezione dei generatori di codice sorgente. Alcuni set di lint vengono definiti e utilizzati per convalidare il codice sorgente del modulo. I valori possibili per questi set di lint sono:

  • default l'insieme predefinito di lint, a seconda della posizione del modulo
  • android il set di lint più rigoroso che si applica a tutto il codice della piattaforma Android
  • vendor un insieme di lint meno rigorosi applicati al codice del fornitore
  • none per ignorare tutti gli avvisi e gli errori di lint

clippy_lints

Anche il linter Clippy viene eseguito per impostazione predefinita per tutti i tipi di moduli, ad eccezione dei generatori di codice sorgente. Sono definiti alcuni set di lint che vengono utilizzati per convalidare il codice sorgente del modulo. Ecco alcuni possibili valori:

  • default insieme predefinito di lint a seconda della posizione del modulo
  • android il set di lint più rigoroso che si applica a tutto il codice della piattaforma Android
  • vendor un insieme di lint meno rigorosi applicati al codice del fornitore
  • none per ignorare tutti gli avvisi e gli errori di lint

edizione

edition definisce la versione di Rust da utilizzare per compilare questo codice. È simile alle versioni std per C e C++. I valori validi sono 2015, 2018 e 2021 (predefinito).

flags

flags contiene un elenco di stringhe di flag da passare a rustc durante la compilazione.

ld_flags

ld-flags contiene un elenco di stringhe di flag da passare al linker durante la compilazione del codice sorgente. Questi vengono passati dal flag -C linker-args rustc. clang viene utilizzato come front-end del linker, che richiama lld per il collegamento effettivo.

funzioni

features è un elenco di stringhe di funzionalità che devono essere attivate durante la compilazione. Questo viene passato a rustc da --cfg 'feature="foo"'. La maggior parte delle funzionalità è additiva, quindi in molti casi è costituito dall'insieme completo di funzionalità richiesto da tutti i moduli dipendenti. Tuttavia, nei casi in cui le funzionalità sono esclusive l'una dell'altra, definisci moduli aggiuntivi in eventuali file di compilazione che forniscono funzionalità in conflitto.

cfgs

cfgs contiene un elenco di stringhe di flag cfg da attivare durante la compilazione. Questo viene passato a rustc da --cfg foo e --cfg "fizz=buzz".

Il sistema di compilazione imposta automaticamente determinati flag cfg in determinate situazioni, elencate di seguito:

  • I moduli compilati come dylib avranno il cfg impostato su android_dylib.

  • I moduli che utilizzano il VNDK avranno il cfg android_vndk impostato. È simile alla definizione di __ANDROID_VNDK__ per C++.

strip

strip controlla se e come viene rimosso il file di output (se applicabile). Se non viene impostato, per impostazione predefinita i moduli del dispositivo rimuovono tutto tranne mini debuginfo. Per impostazione predefinita, i moduli host non rimuovono alcun simbolo. I valori validi includono none per disattivare lo stripping e all per rimuovere tutto, incluso il mini debuginfo. Ulteriori valori sono disponibili nel riferimento ai moduli Soong.

host_supported

Per i moduli del dispositivo, il parametro host_supported indica se il modulo deve fornire anche una variante host.

Definisci le dipendenze delle librerie

I moduli Rust possono dipendere sia dalle librerie CC sia da quelle Rust tramite le seguenti proprietà:

Nome proprietà Descrizione
rustlibs Elenco dei moduli rust_library che sono anche dipendenze. Utilizzalo come metodo preferito per dichiarare le dipendenze, in quanto consente al sistema di compilazione di selezionare il collegamento preferito. (vedi Quando esegui il collegamento alle librerie Rust di seguito)
rlibs Elenco dei moduli rust_library che devono essere collegati in modo statico come rlibs. (da usare con cautela; consulta Quando esegui il collegamento alle librerie Rust di seguito.)
shared_libs Elenco dei moduli cc_library che devono essere collegati dinamicamente come librerie condivise.
static_libs Elenco dei moduli cc_library che devono essere collegati staticamente come librerie statiche.
whole_static_libs Elenco dei moduli cc_library che devono essere collegati in modo statico come librerie statiche e inclusi nella libreria risultante. Per le varianti rust_ffi_static, whole_static_libraries verrà incluso nell'archivio della libreria statica risultante. Per le varianti rust_library_rlib, le librerie whole_static_libraries verranno raggruppate nella libreria rlib risultante.

Quando esegui il collegamento con le librerie Rust, come miglior prassi, utilizza la proprietà rustlibs anziché rlibs o dylibs, a meno che tu non abbia un motivo specifico per farlo. In questo modo, il sistema di compilazione può selezionare il collegamento corretto in base alle esigenze del modulo principale e riduce la possibilità che un albero delle dipendenze contenga sia le versioni rlib sia quelle dylib di una libreria (il che causerà l'errore di compilazione).

Funzionalità di compilazione non supportate e con supporto limitato

Rust di Soong offre un supporto limitato per le immagini e gli snapshot vendor e vendor_ramdisk. Tuttavia, staticlibs, cdylibs, rlibs e binaries sono supportati. Per i target di compilazione delle immagini del fornitore, è impostata la proprietà android_vndk cfg. Puoi utilizzarlo nel codice se esistono differenze tra i target del sistema e del fornitore. rust_proc_macros non vengono acquisiti come parte degli snapshot del fornitore. Se sono presenti dipendenze, assicurati di eseguire il controllo della versione in modo appropriato.

Le immagini del prodotto, VNDK e di ripristino non sono supportate.

Build incrementali

Gli sviluppatori possono attivare la compilazione incrementale del codice sorgente di Rust impostando la variabile di ambiente SOONG_RUSTC_INCREMENTAL su true.

Avviso: non è garantito che vengano prodotti file binari identici a quelli generati da BuildBot. Gli indirizzi delle funzioni o dei dati contenuti nei file oggetto potrebbero essere diversi. Per assicurarti che gli elementi generati siano uguali al 100% a quelli creati dall'infrastruttura EngProd, lascia questo valore non impostato.