Auf dieser Seite erhalten Sie einen Überblick darüber, wie die generierte Quelle unterstützt wird, und wie es im Build-System verwendet werden kann.
Alle Quellgeneratoren bieten ähnliche Build-Systemfunktionen. Die drei Vom Build-System unterstützte Anwendungsfälle für die Quellengenerierung sind das Generieren von C-Bindungen. mit Bindgen-, AIDL- und protobuf-Schnittstellen.
Kisten aus generierter Quelle
Jedes Rust-Modul, das Quellcode generiert, kann wie eine Kiste verwendet werden,
wenn es als rust_library
definiert wäre. (Das heißt, sie kann definiert werden als
Abhängigkeit in den Attributen rustlibs
, rlibs
und dylibs
.) Optimale Nutzung
Muster für Plattformcode besteht darin, die generierte Quelle als Kiste zu verwenden. Obwohl die
Für die generierte Quelle wird das include!
-Makro unterstützt. Der Hauptzweck besteht darin,
Drittanbietercode unterstützen, der sich in external/
befindet.
Es kann vorkommen, dass Plattformcode immer noch die generierte Quelle über die
include!()
-Makro, z. B. wenn Sie ein genrule
-Modul zum Generieren einer Quelle verwenden
auf einzigartige Weise nutzen.
Verwenden Sie „include!()“, um die generierte Quelle einzuschließen
Die Verwendung der generierten Quelle als Kiste wird durch die Beispiele in den einzelnen
bzw. der jeweiligen Modulseite. In diesem Abschnitt wird gezeigt, wie auf die generierte Quelle verwiesen wird.
über das include!()
-Makro. Dieser Vorgang ist für alle Quellen ähnlich
Generatoren.
Voraussetzung
Bei diesem Beispiel wird davon ausgegangen, dass Sie eine rust_bindgen
definiert haben.
(libbuzz_bindgen
) und können mit den Schritten zum Einbeziehen der generierten Quelle fortfahren.
für die Verwendung des include!()
-Makros. Wenn Sie dies noch nicht getan haben, lesen Sie den Abschnitt Rost-Bindgen-Modul definieren.
Erstellen Sie libbuzz_bindgen
und kehren Sie dann hierher zurück.
Beachten Sie, dass die darin enthaltenen Build-Datei-Teile für alle Quellgeneratoren gelten.
Schritte zum Einbeziehen der generierten Quelle
Erstellen Sie external/rust/hello_bindgen/Android.bp
mit folgendem Inhalt:
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",
],
}
Erstellen Sie external/rust/hello_bindgen/src/bindings.rs
mit folgendem Inhalt:
#![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"));
Erstellen Sie external/rust/hello_bindgen/src/lib.rs
mit folgendem Inhalt:
mod bindings;
fn main() {
let mut x = bindings::foo { x: 2 };
unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}
Warum Kisten für generierte Quelle
Im Gegensatz zu C/C++-Compilern akzeptiert rustc
nur eine einzelne Quelldatei
die einen Einstiegspunkt für eine Binärdatei oder eine Bibliothek darstellen. Es wird erwartet, dass die Quelle
ist so strukturiert, dass alle erforderlichen Quelldateien automatisch
gefunden. Das bedeutet, dass die generierte Quelle entweder in der Quelle platziert werden muss
oder über eine Einschlussanweisung in der Quelle bereitgestellt werden:
include!("/path/to/hello.rs");
Die Rust-Community hängt von build.rs
-Skripten und Annahmen über
der Cargo-Build-Umgebung, um mit diesem Unterschied zu arbeiten.
Beim Erstellen wird mit dem Befehl cargo
eine Umgebungsvariable OUT_DIR
festgelegt.
in die build.rs
-Skripts voraussichtlich den generierten Quellcode einfügen. Verwenden Sie die Methode
folgenden Befehl, um Quellcode einzubinden:
include!(concat!(env!("OUT_DIR"), "/hello.rs"));
Das stellt für Soong eine Herausforderung dar, da die Ausgaben für jedes Modul
ein eigenes out/
-Verzeichnis1 erstellen. Es gibt nicht eine einzige OUT_DIR
, bei der
Abhängigkeiten ihre generierte Quelle ausgeben.
Für Plattformcode bevorzugt AOSP die Verpackung der generierten Quelle in eine Kiste, die kann aus verschiedenen Gründen importiert werden:
- Verhindern, dass generierte Quelldateinamen kollidieren.
- Boilerplate-Code reduzieren in dem Baum, der gewartet werden muss, eingecheckt haben. Textbausteine, die erforderlich, damit die generierte Quelle kompiliert wird in einer Kiste zentral gepflegt werden.
- Vermeiden Sie implizite2 Interaktionen zwischen dem generierten Code und dem umgebenden Container.
- Reduzieren Sie Speicher- und Laufwerksauslastung, indem Sie häufig verwendete Quellen dynamisch verknüpfen.
Infolgedessen erzeugen alle Modultypen der Rust-Quellengenerierung von Android Code
das zusammengestellt und als Kiste verwendet werden kann.
Soong unterstützt Kisten von Drittanbietern weiterhin, ohne dass Änderungen erforderlich sind, wenn alle
Die generierten Quellabhängigkeiten für ein Modul werden pro Modul in ein einzelnes kopiert
ähnlich wie Cargo. In solchen Fällen legt Soong die Umgebungsvariable OUT_DIR
fest.
in dieses Verzeichnis verschieben, wenn Sie das Modul kompilieren, damit die generierte Quelle gefunden werden kann.
Aus den bereits beschriebenen Gründen ist es jedoch eine bewährte Methode, nur
dieser Mechanismus im Plattformcode ein,
wenn es unbedingt erforderlich ist.
-
Dies stellt keine Probleme für C/C++ und ähnliche Sprachen dar, da die Der Pfad zur generierten Quelle wird dem Compiler direkt bereitgestellt.↩
-
Da
include!
auf Text eingeschlossen ist, kann es auf Werte aus den einschließenden Namespace, ändern Sie den Namespace oder verwenden Sie Konstrukte wie#![foo]
. Es kann schwierig sein, diese impliziten Interaktionen zu verwalten. Immer bevorzugen wenn eine Interaktion mit dem Rest der Kiste wirklich erforderlich ist.↩