Générateurs de sources

Cette page fournit une vue générale de la manière dont la source générée est prise en charge et de la manière dont elle peut être utilisée dans le système de build.

Tous les générateurs de sources fournissent des fonctionnalités de système de construction similaires. Les trois cas d'utilisation de génération de sources pris en charge par le système de construction génèrent des liaisons C à l'aide des interfaces bindgen, AIDL et protobuf.

Caisses à partir de la source générée

Chaque module Rust qui génère du code source peut être utilisé comme une caisse, exactement comme s'il était défini comme rust_library . (Cela signifie qu'il peut être défini comme une dépendance dans les propriétés rustlibs , rlibs et dylibs .) Le meilleur modèle d'utilisation du code de plate-forme consiste à utiliser la source générée comme caisse. Bien que l' include! La macro est prise en charge pour la source générée, son objectif principal est de prendre en charge le code tiers qui réside dans external/ .

Il existe des cas où le code de la plate-forme peut toujours utiliser la source générée via la macro include!() , par exemple lorsque vous utilisez un module genrule pour générer la source de manière unique.

Utilisez include!() pour inclure la source générée

L'utilisation de la source générée comme caisse est couverte par les exemples de chaque page de module spécifique (respective). Cette section montre comment référencer la source générée via la macro include!() . Notez que ce processus est similaire pour tous les générateurs de sources.

Prérequis

Cet exemple est basé sur l'hypothèse que vous avez défini un module rust_bindgen ( libbuzz_bindgen ) et que vous pouvez passer aux étapes d'inclusion de la source générée pour utiliser la macro include!() . Si ce n'est pas le cas, veuillez consulter Définition d'un module rust bindgen , créez libbuzz_bindgen , puis revenez ici.

Notez que les parties du fichier de construction sont applicables à tous les générateurs de sources.

Étapes pour inclure la source générée

Créez external/rust/hello_bindgen/Android.bp avec le contenu suivant :

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",
    ],
}

Créez external/rust/hello_bindgen/src/bindings.rs avec le contenu suivant :

#![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"));

Créez external/rust/hello_bindgen/src/lib.rs avec le contenu suivant :

mod bindings;

fn main() {
    let mut x = bindings::foo { x: 2 };
    unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}

Pourquoi des caisses pour la source générée

Contrairement aux compilateurs C/C++, rustc n'accepte qu'un seul fichier source représentant un point d'entrée vers un binaire ou une bibliothèque. Il s'attend à ce que l'arborescence source soit structurée de telle sorte que tous les fichiers source requis puissent être automatiquement découverts. Cela signifie que la source générée doit être soit placée dans l'arborescence des sources, soit fournie via une directive include dans la source :

include!("/path/to/hello.rs");

La communauté Rust dépend des scripts build.rs et des hypothèses concernant l'environnement de construction Cargo, pour fonctionner avec cette différence . Lors de sa construction, la commande cargo définit une variable d'environnement OUT_DIR dans laquelle les scripts build.rs sont censés placer le code source généré. Utilisez la commande suivante pour inclure le code source :

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

Cela représente un défi pour Soong car les sorties de chaque module sont placées dans leur propre répertoire out/ 1 . Il n'existe pas un seul OUT_DIR où les dépendances génèrent leur source générée.

Pour le code de la plate-forme, AOSP préfère regrouper la source générée dans une caisse qui peut être importée, pour plusieurs raisons :

  • Empêchez les noms de fichiers sources générés d'entrer en collision.
  • Réduisez le code passe -partout enregistré dans toute l’arborescence qui nécessite une maintenance. Tout passe-partout requis pour compiler la source générée dans une caisse peut être géré de manière centralisée.
  • Évitez les interactions implicites 2 entre le code généré et la caisse environnante.
  • Réduisez la pression sur la mémoire et le disque en reliant dynamiquement les sources générées couramment utilisées.

En conséquence, tous les types de modules de génération de sources Rust d'Android produisent du code qui peut être compilé et utilisé comme crate . Soong prend toujours en charge les caisses tierces sans modification si toutes les dépendances sources générées pour un module sont copiées dans un seul répertoire par module, similaire à Cargo. Dans de tels cas, Soong définit la variable d'environnement OUT_DIR sur ce répertoire lors de la compilation du module, afin que la source générée puisse être trouvée. Cependant, pour les raisons déjà décrites, il est préférable de n'utiliser ce mécanisme dans le code de la plateforme que lorsque cela est absolument nécessaire.


  1. Cela ne pose aucun problème pour le C/C++ et les langages similaires, car le chemin d'accès à la source générée est fourni directement au compilateur.

  2. Depuis include! fonctionne par inclusion textuelle, il peut référencer des valeurs de l'espace de noms englobant, modifier l'espace de noms ou utiliser des constructions comme #![foo] . Ces interactions implicites peuvent être difficiles à maintenir. Préférez toujours les macros lorsqu'une interaction avec le reste de la caisse est vraiment requise.

,

Cette page fournit une vue générale de la manière dont la source générée est prise en charge et de la manière dont elle peut être utilisée dans le système de build.

Tous les générateurs de sources fournissent des fonctionnalités de système de construction similaires. Les trois cas d'utilisation de génération de sources pris en charge par le système de construction génèrent des liaisons C à l'aide des interfaces bindgen, AIDL et protobuf.

Caisses à partir de la source générée

Chaque module Rust qui génère du code source peut être utilisé comme une caisse, exactement comme s'il était défini comme rust_library . (Cela signifie qu'il peut être défini comme une dépendance dans les propriétés rustlibs , rlibs et dylibs .) Le meilleur modèle d'utilisation du code de plate-forme consiste à utiliser la source générée comme caisse. Bien que l' include! La macro est prise en charge pour la source générée, son objectif principal est de prendre en charge le code tiers qui réside dans external/ .

Il existe des cas où le code de la plate-forme peut toujours utiliser la source générée via la macro include!() , par exemple lorsque vous utilisez un module genrule pour générer la source de manière unique.

Utilisez include!() pour inclure la source générée

L'utilisation de la source générée comme caisse est couverte par les exemples de chaque page de module spécifique (respective). Cette section montre comment référencer la source générée via la macro include!() . Notez que ce processus est similaire pour tous les générateurs de sources.

Prérequis

Cet exemple est basé sur l'hypothèse que vous avez défini un module rust_bindgen ( libbuzz_bindgen ) et que vous pouvez passer aux étapes d'inclusion de la source générée pour utiliser la macro include!() . Si ce n'est pas le cas, veuillez consulter Définition d'un module rust bindgen , créez libbuzz_bindgen , puis revenez ici.

Notez que les parties du fichier de construction sont applicables à tous les générateurs de sources.

Étapes pour inclure la source générée

Créez external/rust/hello_bindgen/Android.bp avec le contenu suivant :

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",
    ],
}

Créez external/rust/hello_bindgen/src/bindings.rs avec le contenu suivant :

#![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"));

Créez external/rust/hello_bindgen/src/lib.rs avec le contenu suivant :

mod bindings;

fn main() {
    let mut x = bindings::foo { x: 2 };
    unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}

Pourquoi des caisses pour la source générée

Contrairement aux compilateurs C/C++, rustc n'accepte qu'un seul fichier source représentant un point d'entrée vers un binaire ou une bibliothèque. Il s'attend à ce que l'arborescence source soit structurée de telle sorte que tous les fichiers source requis puissent être automatiquement découverts. Cela signifie que la source générée doit être soit placée dans l'arborescence des sources, soit fournie via une directive include dans la source :

include!("/path/to/hello.rs");

La communauté Rust dépend des scripts build.rs et des hypothèses concernant l'environnement de construction Cargo, pour fonctionner avec cette différence . Lors de sa construction, la commande cargo définit une variable d'environnement OUT_DIR dans laquelle les scripts build.rs sont censés placer le code source généré. Utilisez la commande suivante pour inclure le code source :

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

Cela représente un défi pour Soong car les sorties de chaque module sont placées dans leur propre répertoire out/ 1 . Il n'existe pas un seul OUT_DIR où les dépendances génèrent leur source générée.

Pour le code de la plate-forme, AOSP préfère regrouper la source générée dans une caisse qui peut être importée, pour plusieurs raisons :

  • Empêchez les noms de fichiers sources générés d'entrer en collision.
  • Réduisez le code passe -partout enregistré dans toute l’arborescence qui nécessite une maintenance. Tout passe-partout requis pour compiler la source générée dans une caisse peut être géré de manière centralisée.
  • Évitez les interactions implicites 2 entre le code généré et la caisse environnante.
  • Réduisez la pression sur la mémoire et le disque en reliant dynamiquement les sources générées couramment utilisées.

En conséquence, tous les types de modules de génération de sources Rust d'Android produisent du code qui peut être compilé et utilisé comme crate . Soong prend toujours en charge les caisses tierces sans modification si toutes les dépendances sources générées pour un module sont copiées dans un seul répertoire par module, similaire à Cargo. Dans de tels cas, Soong définit la variable d'environnement OUT_DIR sur ce répertoire lors de la compilation du module, afin que la source générée puisse être trouvée. Cependant, pour les raisons déjà décrites, il est préférable de n'utiliser ce mécanisme dans le code de la plateforme que lorsque cela est absolument nécessaire.


  1. Cela ne pose aucun problème pour le C/C++ et les langages similaires, car le chemin d'accès à la source générée est fourni directement au compilateur.

  2. Depuis include! fonctionne par inclusion textuelle, il peut référencer des valeurs de l'espace de noms englobant, modifier l'espace de noms ou utiliser des constructions comme #![foo] . Ces interactions implicites peuvent être difficiles à maintenir. Préférez toujours les macros lorsqu'une interaction avec le reste de la caisse est vraiment requise.

,

Cette page fournit une vue générale de la manière dont la source générée est prise en charge et de la manière dont elle peut être utilisée dans le système de build.

Tous les générateurs de sources fournissent des fonctionnalités de système de construction similaires. Les trois cas d'utilisation de génération de sources pris en charge par le système de construction génèrent des liaisons C à l'aide des interfaces bindgen, AIDL et protobuf.

Caisses à partir de la source générée

Chaque module Rust qui génère du code source peut être utilisé comme une caisse, exactement comme s'il était défini comme rust_library . (Cela signifie qu'il peut être défini comme une dépendance dans les propriétés rustlibs , rlibs et dylibs .) Le meilleur modèle d'utilisation du code de plate-forme consiste à utiliser la source générée comme caisse. Bien que l' include! La macro est prise en charge pour la source générée, son objectif principal est de prendre en charge le code tiers qui réside dans external/ .

Il existe des cas où le code de la plate-forme peut toujours utiliser la source générée via la macro include!() , par exemple lorsque vous utilisez un module genrule pour générer la source de manière unique.

Utilisez include!() pour inclure la source générée

L'utilisation de la source générée comme caisse est couverte par les exemples de chaque page de module spécifique (respective). Cette section montre comment référencer la source générée via la macro include!() . Notez que ce processus est similaire pour tous les générateurs de sources.

Prérequis

Cet exemple est basé sur l'hypothèse que vous avez défini un module rust_bindgen ( libbuzz_bindgen ) et que vous pouvez passer aux étapes d'inclusion de la source générée pour utiliser la macro include!() . Si ce n'est pas le cas, veuillez consulter Définition d'un module rust bindgen , créez libbuzz_bindgen , puis revenez ici.

Notez que les parties du fichier de construction sont applicables à tous les générateurs de sources.

Étapes pour inclure la source générée

Créez external/rust/hello_bindgen/Android.bp avec le contenu suivant :

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",
    ],
}

Créez external/rust/hello_bindgen/src/bindings.rs avec le contenu suivant :

#![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"));

Créez external/rust/hello_bindgen/src/lib.rs avec le contenu suivant :

mod bindings;

fn main() {
    let mut x = bindings::foo { x: 2 };
    unsafe { bindings::fizz(1, &mut x as *mut bindings::foo) }
}

Pourquoi des caisses pour la source générée

Contrairement aux compilateurs C/C++, rustc n'accepte qu'un seul fichier source représentant un point d'entrée vers un binaire ou une bibliothèque. Il s'attend à ce que l'arborescence source soit structurée de telle sorte que tous les fichiers source requis puissent être automatiquement découverts. Cela signifie que la source générée doit être soit placée dans l'arborescence des sources, soit fournie via une directive include dans la source :

include!("/path/to/hello.rs");

La communauté Rust dépend des scripts build.rs et des hypothèses concernant l'environnement de construction Cargo, pour fonctionner avec cette différence . Lors de sa construction, la commande cargo définit une variable d'environnement OUT_DIR dans laquelle les scripts build.rs sont censés placer le code source généré. Utilisez la commande suivante pour inclure le code source :

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

Cela représente un défi pour Soong car les sorties de chaque module sont placées dans leur propre répertoire out/ 1 . Il n'existe pas un seul OUT_DIR où les dépendances génèrent leur source générée.

Pour le code de la plate-forme, AOSP préfère regrouper la source générée dans une caisse qui peut être importée, pour plusieurs raisons :

  • Empêchez les noms de fichiers sources générés d'entrer en collision.
  • Réduisez le code passe -partout enregistré dans toute l’arborescence qui nécessite une maintenance. Tout passe-partout requis pour compiler la source générée dans une caisse peut être géré de manière centralisée.
  • Évitez les interactions implicites 2 entre le code généré et la caisse environnante.
  • Réduisez la pression sur la mémoire et le disque en reliant dynamiquement les sources générées couramment utilisées.

En conséquence, tous les types de modules de génération de sources Rust d'Android produisent du code qui peut être compilé et utilisé comme crate . Soong prend toujours en charge les caisses tierces sans modification si toutes les dépendances sources générées pour un module sont copiées dans un seul répertoire par module, similaire à Cargo. Dans de tels cas, Soong définit la variable d'environnement OUT_DIR sur ce répertoire lors de la compilation du module, afin que la source générée puisse être trouvée. Cependant, pour les raisons déjà décrites, il est préférable de n'utiliser ce mécanisme dans le code de la plateforme que lorsque cela est absolument nécessaire.


  1. Cela ne pose aucun problème pour le C/C++ et les langages similaires, car le chemin d'accès à la source générée est fourni directement au compilateur.

  2. Depuis include! fonctionne par inclusion textuelle, il peut référencer des valeurs de l'espace de noms englobant, modifier l'espace de noms ou utiliser des constructions comme #![foo] . Ces interactions implicites peuvent être difficiles à maintenir. Préférez toujours les macros lorsqu'une interaction avec le reste de la caisse est vraiment requise.