Geradores de origem

Esta página fornece uma visão de alto nível de como a fonte gerada é suportada e como ela pode ser usada no sistema de compilação.

Todos os geradores de origem fornecem funcionalidade de sistema de compilação semelhante. Os três casos de uso de geração de origem suportados pelo sistema de compilação estão gerando ligações C usando bindgen, interfaces AIDL e interfaces protobuf.

Caixas da fonte gerada

Cada módulo Rust que gera código-fonte pode ser usado como uma caixa, exatamente como se fosse definido como rust_library . (Isso significa que pode ser definido como uma dependência nas propriedades rustlibs , rlibs e dylibs .) O melhor padrão de uso para código de plataforma é empregar a fonte gerada como uma caixa. Embora include! macro é compatível com a fonte gerada, seu objetivo principal é oferecer suporte a código de terceiros que reside em external/ .

Há casos em que o código da plataforma ainda pode usar o código-fonte gerado por meio da macro include!() , como quando você usa um módulo genrule para gerar o código-fonte de uma maneira exclusiva.

Use include!() para incluir a fonte gerada

O uso da fonte gerada como uma caixa é abordado pelos exemplos em cada página específica (respectiva) do módulo. Esta seção mostra como fazer referência à fonte gerada por meio da macro include!() . Observe que este processo é semelhante para todos os geradores de origem.

Pré-requisito

Este exemplo é baseado na suposição de que você definiu um módulo rust_bindgen ( libbuzz_bindgen ) e pode prosseguir para as Etapas para incluir a fonte gerada para usar a macro include!() . Caso ainda não tenha feito isso, vá para Definindo um módulo Rust Bindgen , crie libbuzz_bindgen e retorne aqui.

Observe que as partes do arquivo de construção são aplicáveis ​​a todos os geradores de origem.

Etapas para incluir a fonte gerada

Crie external/rust/hello_bindgen/Android.bp com o seguinte conteúdo:

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

Crie external/rust/hello_bindgen/src/bindings.rs com o seguinte conteúdo:

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

Crie external/rust/hello_bindgen/src/lib.rs com o seguinte conteúdo:

mod bindings;

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

Por que caixas para fonte gerada

Ao contrário dos compiladores C/C++, rustc aceita apenas um único arquivo de origem que representa um ponto de entrada para um binário ou biblioteca. Ele espera que a árvore de origem seja estruturada de forma que todos os arquivos de origem necessários possam ser descobertos automaticamente. Isso significa que a fonte gerada deve ser colocada na árvore de origem ou fornecida através de uma diretiva include na fonte:

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

A comunidade Rust depende de scripts build.rs e suposições sobre o ambiente de construção Cargo para trabalhar com essa diferença . Ao compilar, o comando cargo define uma variável de ambiente OUT_DIR na qual se espera que os scripts build.rs coloquem o código-fonte gerado. Use o seguinte comando para incluir o código-fonte:

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

Isso representa um desafio para o Soong, pois as saídas de cada módulo são colocadas em seu próprio diretório out/ 1 . Não há um único OUT_DIR onde as dependências geram sua fonte gerada.

Para o código da plataforma, o AOSP prefere empacotar a fonte gerada em uma caixa que possa ser importada, por vários motivos:

  • Evite que os nomes dos arquivos de origem gerados colidam.
  • Reduza o check-in do código clichê em toda a árvore que requer manutenção. Qualquer padrão necessário para compilar a fonte gerada em uma caixa pode ser mantido centralmente.
  • Evite interações implícitas entre o código gerado e a caixa circundante.
  • Reduza a pressão na memória e no disco vinculando dinamicamente fontes geradas comumente usadas.

Como resultado, todos os tipos de módulos de geração de código-fonte Rust do Android produzem código que pode ser compilado e usado como um crate . Soong ainda suporta caixas de terceiros sem modificação se todas as dependências de origem geradas para um módulo forem copiadas em um único diretório por módulo, semelhante ao Cargo. Nesses casos, Soong define a variável de ambiente OUT_DIR para esse diretório ao compilar o módulo, para que a fonte gerada possa ser encontrada. No entanto, pelas razões já descritas, é uma prática recomendada usar esse mecanismo apenas no código da plataforma quando for absolutamente necessário.


  1. Isso não apresenta nenhum problema para C/C++ e linguagens similares, já que o caminho para a fonte gerada é fornecido diretamente ao compilador.

  2. Desde include! funciona por inclusão textual, pode fazer referência a valores do namespace anexo, modificar o namespace ou usar construções como #![foo] . Essas interações implícitas podem ser difíceis de manter. Sempre prefira macros quando a interação com o resto da caixa for realmente necessária.

,

Esta página fornece uma visão de alto nível de como a fonte gerada é suportada e como ela pode ser usada no sistema de compilação.

Todos os geradores de origem fornecem funcionalidade de sistema de compilação semelhante. Os três casos de uso de geração de origem suportados pelo sistema de compilação estão gerando ligações C usando interfaces bindgen, AIDL e interfaces protobuf.

Caixas da fonte gerada

Cada módulo Rust que gera código-fonte pode ser usado como uma caixa, exatamente como se fosse definido como rust_library . (Isso significa que pode ser definido como uma dependência nas propriedades rustlibs , rlibs e dylibs .) O melhor padrão de uso para código de plataforma é empregar a fonte gerada como uma caixa. Embora include! macro é compatível com a fonte gerada, seu objetivo principal é oferecer suporte a código de terceiros que reside em external/ .

Há casos em que o código da plataforma ainda pode usar o código-fonte gerado por meio da macro include!() , como quando você usa um módulo genrule para gerar o código-fonte de uma maneira exclusiva.

Use include!() para incluir a fonte gerada

O uso da fonte gerada como uma caixa é abordado pelos exemplos em cada página específica (respectiva) do módulo. Esta seção mostra como fazer referência à fonte gerada por meio da macro include!() . Observe que este processo é semelhante para todos os geradores de origem.

Pré-requisito

Este exemplo é baseado na suposição de que você definiu um módulo rust_bindgen ( libbuzz_bindgen ) e pode prosseguir para as Etapas para incluir a fonte gerada para usar a macro include!() . Caso ainda não tenha feito isso, vá para Definindo um módulo Rust Bindgen , crie libbuzz_bindgen e retorne aqui.

Observe que as partes do arquivo de construção são aplicáveis ​​a todos os geradores de origem.

Etapas para incluir a fonte gerada

Crie external/rust/hello_bindgen/Android.bp com o seguinte conteúdo:

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

Crie external/rust/hello_bindgen/src/bindings.rs com o seguinte conteúdo:

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

Crie external/rust/hello_bindgen/src/lib.rs com o seguinte conteúdo:

mod bindings;

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

Por que caixas para fonte gerada

Ao contrário dos compiladores C/C++, rustc aceita apenas um único arquivo de origem que representa um ponto de entrada para um binário ou biblioteca. Ele espera que a árvore de origem seja estruturada de forma que todos os arquivos de origem necessários possam ser descobertos automaticamente. Isso significa que a fonte gerada deve ser colocada na árvore de origem ou fornecida através de uma diretiva include na fonte:

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

A comunidade Rust depende de scripts build.rs e suposições sobre o ambiente de construção Cargo para trabalhar com essa diferença . Ao compilar, o comando cargo define uma variável de ambiente OUT_DIR na qual se espera que os scripts build.rs coloquem o código-fonte gerado. Use o seguinte comando para incluir o código-fonte:

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

Isso representa um desafio para o Soong, pois as saídas de cada módulo são colocadas em seu próprio diretório out/ 1 . Não há um único OUT_DIR onde as dependências geram sua fonte gerada.

Para o código da plataforma, o AOSP prefere empacotar a fonte gerada em uma caixa que possa ser importada, por vários motivos:

  • Evite que os nomes dos arquivos de origem gerados colidam.
  • Reduza o check-in do código clichê em toda a árvore que requer manutenção. Qualquer padrão necessário para compilar a fonte gerada em uma caixa pode ser mantido centralmente.
  • Evite interações implícitas entre o código gerado e a caixa circundante.
  • Reduza a pressão na memória e no disco vinculando dinamicamente fontes geradas comumente usadas.

Como resultado, todos os tipos de módulos de geração de código-fonte Rust do Android produzem código que pode ser compilado e usado como um crate . Soong ainda suporta caixas de terceiros sem modificação se todas as dependências de origem geradas para um módulo forem copiadas em um único diretório por módulo, semelhante ao Cargo. Nesses casos, Soong define a variável de ambiente OUT_DIR para esse diretório ao compilar o módulo, para que a fonte gerada possa ser encontrada. No entanto, pelas razões já descritas, é uma prática recomendada usar esse mecanismo apenas no código da plataforma quando for absolutamente necessário.


  1. Isso não apresenta nenhum problema para C/C++ e linguagens similares, já que o caminho para a fonte gerada é fornecido diretamente ao compilador.

  2. Desde include! funciona por inclusão textual, pode fazer referência a valores do namespace anexo, modificar o namespace ou usar construções como #![foo] . Essas interações implícitas podem ser difíceis de manter. Sempre prefira macros quando a interação com o resto da caixa for realmente necessária.

,

Esta página fornece uma visão de alto nível de como a fonte gerada é suportada e como ela pode ser usada no sistema de compilação.

Todos os geradores de origem fornecem funcionalidade de sistema de compilação semelhante. Os três casos de uso de geração de origem suportados pelo sistema de compilação estão gerando ligações C usando interfaces bindgen, AIDL e interfaces protobuf.

Caixas da fonte gerada

Cada módulo Rust que gera código-fonte pode ser usado como uma caixa, exatamente como se fosse definido como rust_library . (Isso significa que pode ser definido como uma dependência nas propriedades rustlibs , rlibs e dylibs .) O melhor padrão de uso para código de plataforma é empregar a fonte gerada como uma caixa. Embora include! macro é compatível com a fonte gerada, seu objetivo principal é oferecer suporte a código de terceiros que reside em external/ .

Há casos em que o código da plataforma ainda pode usar o código-fonte gerado por meio da macro include!() , como quando você usa um módulo genrule para gerar o código-fonte de uma maneira exclusiva.

Use include!() para incluir a fonte gerada

O uso da fonte gerada como uma caixa é abordado pelos exemplos em cada página específica (respectiva) do módulo. Esta seção mostra como fazer referência à fonte gerada por meio da macro include!() . Observe que este processo é semelhante para todos os geradores de origem.

Pré-requisito

Este exemplo é baseado na suposição de que você definiu um módulo rust_bindgen ( libbuzz_bindgen ) e pode prosseguir para as Etapas para incluir a fonte gerada para usar a macro include!() . Caso ainda não tenha feito isso, vá para Definindo um módulo Rust Bindgen , crie libbuzz_bindgen e retorne aqui.

Observe que as partes do arquivo de construção são aplicáveis ​​a todos os geradores de origem.

Etapas para incluir a fonte gerada

Crie external/rust/hello_bindgen/Android.bp com o seguinte conteúdo:

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

Crie external/rust/hello_bindgen/src/bindings.rs com o seguinte conteúdo:

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

Crie external/rust/hello_bindgen/src/lib.rs com o seguinte conteúdo:

mod bindings;

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

Por que caixas para fonte gerada

Ao contrário dos compiladores C/C++, rustc aceita apenas um único arquivo de origem que representa um ponto de entrada para um binário ou biblioteca. Ele espera que a árvore de origem seja estruturada de forma que todos os arquivos de origem necessários possam ser descobertos automaticamente. Isso significa que a fonte gerada deve ser colocada na árvore de origem ou fornecida através de uma diretiva include na fonte:

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

A comunidade Rust depende de scripts build.rs e suposições sobre o ambiente de construção Cargo para trabalhar com essa diferença . Ao compilar, o comando cargo define uma variável de ambiente OUT_DIR na qual se espera que os scripts build.rs coloquem o código-fonte gerado. Use o seguinte comando para incluir o código-fonte:

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

Isso representa um desafio para o Soong, pois as saídas de cada módulo são colocadas em seu próprio diretório out/ 1 . Não há um único OUT_DIR onde as dependências geram sua fonte gerada.

Para o código da plataforma, o AOSP prefere empacotar a fonte gerada em uma caixa que possa ser importada, por vários motivos:

  • Evite que os nomes dos arquivos de origem gerados colidam.
  • Reduza o check-in do código clichê em toda a árvore que requer manutenção. Qualquer padrão necessário para compilar a fonte gerada em uma caixa pode ser mantido centralmente.
  • Evite interações implícitas entre o código gerado e a caixa circundante.
  • Reduza a pressão na memória e no disco vinculando dinamicamente fontes geradas comumente usadas.

Como resultado, todos os tipos de módulos de geração de código-fonte Rust do Android produzem código que pode ser compilado e usado como um crate . Soong ainda suporta caixas de terceiros sem modificação se todas as dependências de origem geradas para um módulo forem copiadas em um único diretório por módulo, semelhante ao Cargo. Nesses casos, Soong define a variável de ambiente OUT_DIR para esse diretório ao compilar o módulo, para que a fonte gerada possa ser encontrada. No entanto, pelas razões já descritas, é uma prática recomendada usar esse mecanismo apenas no código da plataforma quando for absolutamente necessário.


  1. Isso não apresenta nenhum problema para C/C++ e linguagens similares, já que o caminho para a fonte gerada é fornecido diretamente ao compilador.

  2. Desde include! funciona por inclusão textual, pode fazer referência a valores do namespace anexo, modificar o namespace ou usar construções como #![foo] . Essas interações implícitas podem ser difíceis de manter. Sempre prefira macros quando a interação com o resto da caixa for realmente necessária.