Gerar middleware

O middleware da linguagem de definição de interface de serviços de veículos (VSIDL, na sigla em inglês) define um conjunto de bibliotecas Rust que criam uma camada de abstração sobre a pilha de comunicação de veículos definidos por software (SDV, na sigla em inglês) para simplificar o uso do ecossistema SDV. O middleware oferece uma maneira padronizada para que os serviços se comuniquem e interajam entre si. O código gerado pelo VSIDLC e o código personalizado usam essas bibliotecas.

O compilador da linguagem de definição de interface de serviços de veículos (VSIDLC, na sigla em inglês) valida definições, gera arquivos de build (Android.bp) que contêm destinos genrule para produzir código de middleware Rust durante o processo de build e cria configurações de implantação nos arquivos VSIDL e protobuf em um catálogo. A Figura 1 mostra a entrada para VSIDLC e a saída gerada por VSIDLC:

Entradas e saídas do VSIDLC

Figura 1. Entradas e saídas do VSIDLC.

Confira a seguir uma explicação do diagrama:

  1. Como entradas, você fornece os seguintes arquivos organizados em diretórios conhecidos como catálogos:

    • Os arquivos proto (com a extensão .proto) contêm estruturas de dados trocadas entre as unidades de serviço definidas pelo VSIDL.
    • Os arquivos VSIDL (com a extensão .vsidl) definem pacotes de serviço, unidades de serviço e propriedade do tipo de unidade.
    • Os arquivos Android.bp em cada diretório de catálogo definem destinos de build rust_protobuf para todos os arquivos proto no catálogo. O VSIDLC usa o crate_name especificado nesses destinos para referenciar os tipos de mensagens protobuf gerados em Rust.
  2. Execute o VSIDLC para gerar os seguintes arquivos:

    • Os arquivos Android.bp são gerados na pasta de cada pacote de serviço. Se você definir --genrule, esses destinos vão gerar arquivos Rust atualizados durante o processo de build e incluir as dependências necessárias da biblioteca rust_protobuf.

    • Os arquivos service_bundle.rs são gerados para cada pacote de serviço e contêm o struct principal e as funções para interagir com os componentes do middleware.

    • Os arquivos lib.rs são gerados para cada serviço RPC pertencente a um pacote e são colocados em uma subpasta com o nome do serviço RPC. Esses arquivos incluem:

    • Um trait Interface implementa a lógica do lado do servidor.

    • Um struct Client faz chamadas para um serviço RPC.

    • Os arquivos diagnostics.rs são gerados se uma diagnostics_declaration estiver presente no arquivo VSIDL, fornecendo as vinculações necessárias para diagnósticos baseados em UDS.

    • As configurações de implantação e segurança são geradas ao usar a flag --apex. Elas são colocadas nos diretórios apex/ e configs/ e incluem arquivos .textproto de orquestração e políticas de segurança (permissões) necessárias para a comunicação entre serviços.

    • Um boilerplate de serviço é gerado ao usar a flag --services. Ele é colocado em um diretório services/ e contém um esqueleto de aplicativo Rust, incluindo um arquivo main.rs, para iniciar a implementação.

Executar o VSIDLC

Para executar o VSIDLC:

  1. Se você não configurou o ambiente, execute source build/envsetup.sh.

  2. Execute o comando a seguir para criar o VSIDLC:

    m vsidlc
    
  3. Verifique se o diretório do catálogo VSIDL tem os arquivos de build, protobuf e VSIDL necessários.

  4. Execute o comando vsidlc:

    vsidlc -c path_to_catalog -o output_directory -p
    

    Em que:

    • -c path_to_catalog identifica o caminho para o diretório do catálogo principal.
    • -o output_directory identifica o diretório pai em que o diretório de saída generated_rs é criado.
    • (opcional) --apex gera artefatos de configuração de orquestração e segurança.
    • (opcional) --services gera um esqueleto de aplicativo Rust de inicialização rápida.
    • (opcional) -p exclui diretórios gerados (como generated_rs e, se aplicável, apex, configs ou services) antes de gerar novos arquivos.
    • (opcional) --genrule gera genrules Android.bp em vez de código Rust. As genrules geram o código Rust necessário em tempo real ao executar m para evitar a colocação de artefatos gerados no controle de versão.

    Um diretório generated_rs é criado contendo um Android.bp e os arquivos de middleware gerados. Esse diretório é organizado em subdiretórios correspondentes aos nomes totalmente qualificados dos pacotes de serviço definidos.

Gerenciar dependências

Por padrão, o VSIDLC gera código apenas para o catálogo principal, não para catálogos de dependência. Se o catálogo usar tipos ou unidades de serviço definidos em outros catálogos, especifique o caminho para cada catálogo de dependência usando a flag -d:

vsidlc -c path_to_catalog -o output_directory -d dep1_path -d dep2_path ...

Você precisa fornecer caminhos para todo o gráfico de dependência, incluindo dependências transitivas (dependências de dependências). Por exemplo, suponha que você tenha a seguinte árvore de dependência de catálogo:

Exemplo de árvore de dependência do VSIDLC

Figura 2. Exemplo de árvore de dependência do VSIDLC.

Para gerar middleware para cada catálogo na árvore, execute os seguintes comandos:

Catálogo de destino Dependências Comando
Catálogo principal do SDV N/A vsidlc -o ./generated -c ./path/to/sdv_core_catalog
Catálogo de diagnósticos Catálogo principal do SDV vsidlc -o ./generated -c ./path/to/diagnostics_catalog -d ./path/to/sdv_core_catalog
Catálogo SOMEIP Catálogo de diagnósticos, catálogo principal do SDV vsidlc -o ./generated -c ./path/to/someip_catalog -d ./path/to/diagnostics_catalog -d ./path/to/sdv_core_catalog
Catálogo OEM Catálogo de diagnósticos, catálogo SOMEIP, (transitivo) catálogo principal do SDV vsidlc -o ./generated -c ./path/to/oem_catalog -d ./path/to/someip_catalog -d ./path/to/diagnostics_catalog -d ./path/to/sdv_core_catalog

Formatar saída do Rust

Por padrão, o VSIDL usa rustfmt para formatar a saída do Rust. Para que o padrão funcione corretamente, defina a variável de ambiente $ANDROID_BUILD_TOP ou as variáveis de ambiente RUSTFMT_PATH e RUSTFMT_TOML_PATH. Para mudar o formato padrão da saída do Rust, use a opção --rust-formatter com pretty-please ou none:

  • Para mudar o formato de saída para o crate prettyplease, use o valor pretty-please:

    vsidlc -c path_to_catalog -o output_directory -p --rust-formatter pretty-please
    
  • Para mudar o formato de saída para nenhum, use o valor none:

    vsidlc -c path_to_catalog -o output_directory -p --rust-formatter none
    

A seguir

Depois de gerar o middleware, consulte Implementar a lógica de negócios.