O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Suporte ao sistema de construção VNDK

No Android 8.1 e superior, o sistema de compilação tem suporte VNDK integrado. Quando o suporte VNDK está habilitado, o sistema de compilação verifica as dependências entre os módulos, cria uma variante específica do fornecedor para os módulos do fornecedor e instala automaticamente esses módulos em diretórios designados.

Exemplo de suporte de construção VNDK

Neste exemplo, o Android.bp definição de módulo define uma biblioteca chamada libexample . O vendor_available propriedade indica módulos de estrutura e módulos de fornecedores pode depender libexample :

libexample vendor_available: true e vndk.enabled: true

Apoio Figura 1. VNDK habilitado

Tanto o quadro executável /system/bin/foo e o fornecedor executável /vendor/bin/bar dependem libexample e ter libexample em suas shared_libs propriedades.

Se libexample é usado por ambos os módulos de estrutura e módulos de fornecedores, duas variantes do libexample são construídas. A variante do núcleo (em homenagem a libexample ) é usado por módulos estruturais ea variante fornecedor (em homenagem a libexample.vendor ) é usado por módulos de fornecedores. As duas variantes são instaladas em diretórios diferentes:

  • A variante do núcleo é instalado em /system/lib[64]/libexample.so .
  • A variante fornecedor é instalado em VNDK APEX porque vndk.enabled é true .

Para mais detalhes, consulte definição Module .

Configurando o suporte de compilação

Para ativar o suporte sistema de compilação completa para um dispositivo de produto, adicionar BOARD_VNDK_VERSION para BoardConfig.mk :

BOARD_VNDK_VERSION := current

Essa configuração tem um efeito global: Quando definido no BoardConfig.mk , todos os módulos são verificados. Como não há nenhum mecanismo para um módulo de ofender blacklist ou whitelist, você deve limpar todas as dependências desnecessárias antes de adicionar BOARD_VNDK_VERSION . Você pode testar e compilar um módulo, definindo BOARD_VNDK_VERSION em suas variáveis de ambiente:

$ BOARD_VNDK_VERSION=current m module_name.vendor

Quando BOARD_VNDK_VERSION está habilitado, vários caminhos de pesquisa padrão cabeçalho mundial são removidos. Esses incluem:

  • frameworks/av/include
  • frameworks/native/include
  • frameworks/native/opengl/include
  • hardware/libhardware/include
  • hardware/libhardware_legacy/include
  • hardware/ril/include
  • libnativehelper/include
  • libnativehelper/include_deprecated
  • system/core/include
  • system/media/audio/include

Se um módulo depende dos cabeçalhos a partir desses diretórios, você deve especificar (explicitamente) as dependências com header_libs , static_libs , e / ou shared_libs .

VNDK APEX

Em Android 10 e inferior, módulos com vndk.enabled foram instalados em /system/lib[64]/vndk[-sp]-${VER} . Em Android 11 e superior, bibliotecas VNDK são embalados em um formato APEX eo nome do VNDK APEX é com.android.vndk.v${VER} . Dependendo da configuração do dispositivo, VNDK APEX é achatada ou não nivelado e está disponível a partir do caminho canónica /apex/com.android.vndk.v${VER} .

VNDK APEX

Figura 2. VNDK APEX

Definição de Módulo

Para construir Android com BOARD_VNDK_VERSION , você deve rever a definição de módulo em qualquer Android.mk ou Android.bp . Esta seção descreve diferentes tipos de definições de módulo, várias propriedades de módulo relacionadas ao VNDK e verificações de dependência implementadas no sistema de construção.

Módulos de fornecedores

Os módulos do fornecedor são executáveis ​​ou bibliotecas compartilhadas específicos do fornecedor que devem ser instalados em uma partição do fornecedor. Em Android.bp arquivos, módulos de fornecedor deve definir fornecedor ou propriedade de propriedade da true . Em Android.mk arquivos, módulos de fornecedor deve definir LOCAL_VENDOR_MODULE ou LOCAL_PROPRIETARY_MODULE a true .

Se BOARD_VNDK_VERSION é definido, o sistema de construção não permite dependências entre os módulos de fornecedores e módulos quadro e emite erros se:

  • um módulo sem vendor:true depende de um módulo com vendor:true , ou
  • um módulo com vendor:true depende de um não- llndk_library módulo que não tem nem vendor:true nem vendor_available:true .

A verificação de dependência se aplica a header_libs , static_libs e shared_libs em Android.bp , e LOCAL_HEADER_LIBRARIES , LOCAL_STATIC_LIBRARIES e LOCAL_SHARED_LIBRARIES em Android.mk .

LL-NDK

Bibliotecas compartilhadas LL-NDK são bibliotecas compartilhadas com ABIs estáveis. Os módulos da estrutura e do fornecedor compartilham a mesma implementação e a mais recente. Para cada LL-NDK biblioteca compartilhada, Android.bp contém uma llndk_library definição de módulo:

llndk_library {
    name: "libvndksupport",
    symbol_file: "libvndksupport.map.txt",
}

Esta definição de módulo especifica um nome de módulo e um arquivo de símbolo que descreve os símbolos visíveis aos módulos do fornecedor. Por exemplo:

LIBVNDKSUPPORT {
  global:
    android_load_sphal_library; # llndk
    android_unload_sphal_library; # llndk
  local:
    *;
};

Com base no arquivo de símbolo, o sistema de compilação gera uma biblioteca compartilhada stub para módulos de fornecedores, que ligam com estas bibliotecas quando BOARD_VNDK_VERSION está habilitado. Um símbolo é incluído na biblioteca compartilhada stub apenas se:

  • Não é definido no final seção com _PRIVATE ou _PLATFORM ,
  • Não tem #platform-only tag, e
  • Não tem #introduce* tags ou os jogos de tag com o alvo.

VNDK

Em Android.bp arquivos, cc_library , cc_library_static , cc_library_shared e cc_library_headers módulo definições apoiar três propriedades relacionadas à VNDK: vendor_available , vndk.enabled e vndk.support_system_process .

Se vendor_available ou vndk.enabled é true , duas variantes (núcleo e fornecedor) pode ser construído. A variante principal deve ser tratada como um módulo de estrutura e a variante do fornecedor deve ser tratada como um módulo do fornecedor. Se alguns módulos de estrutura dependem deste módulo, a variante principal é construída. Se alguns módulos do fornecedor dependem deste módulo, a variante do fornecedor é construída. O sistema de compilação impõe as seguintes verificações de dependência:

  • A variante principal é sempre apenas de estrutura e inacessível aos módulos do fornecedor.
  • A variante do fornecedor está sempre inacessível aos módulos da estrutura.
  • Todas as dependências da variante fornecedor, que são especificados na header_libs , static_libs , e / ou shared_libs , deve ser um llndk_library ou um módulo com vendor_available ou vndk.enabled .
  • Se vendor_available é true , a variante fornecedor é acessível a todos os módulos do fornecedor.
  • Se vendor_available é false , a variante fornecedor só é acessível a outros VNDK ou módulos VNDK-SP (ou seja, módulos com vendor:true lata não apontam vendor_available:false módulos).

O caminho de instalação padrão para cc_library ou cc_library_shared é determinado pelas regras o seguinte:

  • A variante do núcleo é instalado para /system/lib[64] .
  • O caminho de instalação da variante do fornecedor pode variar:
    • Se vndk.enabled é false , a variante fornecedor é instalado em /vendor/lib[64] .
    • Se vndk.enabled é true , a variante fornecedor é instalado em VNDK APEX ( com.android.vndk.v${VER} ).

A tabela abaixo resume como o sistema de compilação lida com as variantes do fornecedor:

vendor_available vndk
ativado
vndk
support_same_process
Descrições de variantes de fornecedores
true false false As variantes de fornecedor são VND-ONLY. Bibliotecas compartilhadas são instalados em /vendor/lib[64] .
true Inválido (erro de compilação)
true false As variantes de fornecedor são VNDK. Bibliotecas compartilhadas são instaladas no VNDK APEX.
true As variantes de fornecedor são VNDK-SP. Bibliotecas compartilhadas são instaladas no VNDK APEX.

false

false

false

Sem variantes de fornecedor. Este módulo é FWK-ONLY.

true Inválido (erro de compilação)
true false As variantes de fornecedor são VNDK-Privada. Bibliotecas compartilhadas são instaladas no VNDK APEX. Eles não devem ser usados ​​diretamente pelos módulos do fornecedor.
true As variantes de fornecedor são-VNDK-SP Privado. Bibliotecas compartilhadas são instaladas no VNDK APEX. Eles não devem ser usados ​​diretamente pelos módulos do fornecedor.

Extensões VNDK

Extensões VNDK são bibliotecas VNDK compartilhadas com APIs adicionais. Extensões são instalados /vendor/lib[64]/vndk[-sp] (sem versão sufixo) e substituir o VNDK originais bibliotecas compartilhadas em tempo de execução.

Definindo extensões VNDK

Em Android 9 e superior, Android.bp nativamente suporta extensões VNDK. Para construir uma extensão VNDK, definir um outro módulo com um vendor:true e um extends imóvel:

cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
}

Um módulo com vendor:true , vndk.enabled:true , e extends propriedades define a extensão VNDK:

  • O extends propriedade deve especificar uma base VNDK nome da biblioteca compartilhada (ou VNDK-SP nome da biblioteca compartilhada).
  • As extensões VNDK (ou extensões VNDK-SP) são nomeadas de acordo com os nomes dos módulos básicos dos quais se estendem. Por exemplo, o binário de saída libvndk_ext é libvndk.so vez de libvndk_ext.so .
  • VNDK extensões são instalados em /vendor/lib[64]/vndk .
  • Extensões VNDK-SP são instalados em /vendor/lib[64]/vndk-sp .
  • As bibliotecas base compartilhada deve ter tanto vndk.enabled:true e vendor_available:true .

A extensão VNDK-SP deve se estender a partir de uma biblioteca VNDK-SP compartilhada ( vndk.support_system_process deve ser igual):

cc_library {
    name: "libvndk_sp",
    vendor_available: true,
    vndk: {
        enabled: true,
        support_system_process: true,
    },
}

cc_library {
    name: "libvndk_sp_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk_sp",
        support_system_process: true,
    },
}

Extensões VNDK (ou extensões VNDK-SP) podem depender de bibliotecas compartilhadas de outros fornecedores:

cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
    shared_libs: [
        "libvendor",
    ],
}

cc_library {
    name: "libvendor",
    vendor: true,
}

Usando extensões VNDK

Se um módulo fornecedor depende APIs adicionais definidas por extensões VNDK, o módulo deve especificar o nome da extensão VNDK em sua shared_libs propriedade:

// A vendor shared library example
cc_library {
    name: "libvendor",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

// A vendor executable example
cc_binary {
    name: "vendor-example",
    vendor: true,
    shared_libs: [
        "libvndk_ext",
    ],
}

Se um módulo fornecedor depende extensões VNDK, essas extensões VNDK são instalados /vendor/lib[64]/vndk[-sp] automaticamente. Se um módulo não depende mais de uma extensão VNDK, adicionar uma etapa limpa para CleanSpec.mk para remover a biblioteca compartilhada. Por exemplo:

$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)

Compilação condicional

Esta seção descreve como lidar com as diferenças sutis (por exemplo, adicionar ou remover um recurso de uma das variantes) entre os três VNDK seguinte bibliotecas compartilhadas:

  • Variante do núcleo (por exemplo, /system/lib[64]/libexample.so )
  • Variante fornecedor (por exemplo, /apex/com.android.vndk.v${VER}/lib[64]/libexample.so )
  • VNDK extensão (por exemplo /vendor/lib[64]/vndk[-sp]/libexample.so )

Sinalizadores condicionais do compilador

Os define sistema de compilação Android __ANDROID_VNDK__ para variantes de fornecedor e extensões VNDK por padrão. Você pode proteger o código com os protetores do pré-processador C:

void all() { }

#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif

#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif

Além __ANDROID_VNDK__ , diferentes cflags ou cppflags pode ser especificada em Android.bp . Os cflags ou cppflags especificados no target.vendor é específico para a variante fornecedor.

Por exemplo, o seguinte Android.bp define libexample e libexample_ext :

cc_library {
    name: "libexample",
    srcs: ["src/example.c"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
    target: {
        vendor: {
            cflags: ["-DLIBEXAMPLE_ENABLE_VNDK=1"],
        },
    },
}

cc_library {
    name: "libexample_ext",
    srcs: ["src/example.c"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
    cflags: [
        "-DLIBEXAMPLE_ENABLE_VNDK=1",
        "-DLIBEXAMPLE_ENABLE_VNDK_EXT=1",
    ],
}

E esta é a listagem de código de src/example.c :

void all() { }

#if !defined(LIBEXAMPLE_ENABLE_VNDK)
void framework_only() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK)
void vndk() { }
#endif

#if defined(LIBEXAMPLE_ENABLE_VNDK_EXT)
void vndk_ext() { }
#endif

De acordo com esses dois arquivos, o sistema de compilação gera bibliotecas compartilhadas com os seguintes símbolos exportados:

Caminho de instalação Símbolos exportados
/system/lib[64]/libexample.so all , framework_only
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so all , vndk
/vendor/lib[64]/vndk/libexample.so all , vndk , vndk_ext

Requisitos dos símbolos exportados

O verificador VNDK ABI compara o fornecedor de ABI VNDK variantes e extensões VNDK à referência ABI despeja sob prebuilts/abi-dumps/vndk .

  • Símbolos exportados por variantes de fornecedores (por exemplo, VNDK /apex/com.android.vndk.v${VER}/lib[64]/libexample.so ) tem de ser idêntico ao (não os superconjuntos de) os símbolos definidos em ABI lixeiras.
  • Símbolos exportados por extensões VNDK (por exemplo /vendor/lib[64]/vndk/libexample.so ) deve ser superconjuntos dos símbolos definidos em ABI lixeiras.

Se fornecedor VNDK variantes ou extensões VNDK deixar de seguir os requisitos acima, VNDK ABI emite verificador construir erros e pára a compilação.

Excluindo arquivos de origem ou bibliotecas compartilhadas de variantes de fornecedores

Para excluir arquivos de origem da variante fornecedor, adicioná-los à exclude_srcs propriedade. Da mesma forma, as bibliotecas para garantir compartilhados não estão relacionados com a variante fornecedor, adicionar essas bibliotecas ao exclude_shared_libs propriedade. Por exemplo:

cc_library {
    name: "libexample_cond_exclude",
    srcs: ["fwk.c", "both.c"],
    shared_libs: ["libfwk_only", "libboth"],
    vendor_available: true,
    target: {
        vendor: {
            exclude_srcs: ["fwk.c"],
            exclude_shared_libs: ["libfwk_only"],
        },
    },
}

Neste exemplo, a variante de núcleo de libexample_cond_exclude inclui o código de fwk.c e both.c e depende das bibliotecas compartilhadas libfwk_only e libboth . A variante fornecedor de libexample_cond_exclude inclui apenas o código da both.c porque fwk.c é excluída pela exclude_srcs propriedade. Da mesma forma, ele depende apenas a biblioteca compartilhada libboth porque libfwk_only é excluída pela exclude_shared_libs propriedade.

Exportar cabeçalhos de extensões VNDK

Uma extensão VNDK pode adicionar novas classes ou novas funções a uma biblioteca compartilhada VNDK. É recomendável manter essas declarações em cabeçalhos independentes e evitar alterar os cabeçalhos existentes.

Por exemplo, um novo arquivo de cabeçalho include-ext/example/ext/feature_name.h é criada para a extensão VNDK libexample_ext :

  • Android.bp
  • include-ext / example / ext / feature_name.h
  • incluir / exemplo / exemplo.h
  • src / example.c
  • src / ext / feature_name.c

No seguinte Android.bp , libexample exporta apenas include , enquanto libexample_ext exportações tanto include e include-ext . Isso garante feature_name.h não será incluído incorretamente pelos usuários do libexample :

cc_library {
    name: "libexample",
    srcs: ["src/example.c"],
    export_include_dirs: ["include"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libexample_ext",
    srcs: [
        "src/example.c",
        "src/ext/feature_name.c",
    ],
    export_include_dirs: [
        "include",
        "include-ext",
    ],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample",
    },
}

Se separar extensões para arquivos de cabeçalho independentes não é viável, uma alternativa é adicionar #ifdef guardas. No entanto, certifique-se de que todos os usuários de extensão VNDK adicionem os sinalizadores de definição. Você pode definir cc_defaults para adicionar definir sinalizadores para cflags e link compartilhado bibliotecas com shared_libs .

Por exemplo, para adicionar uma nova função membro Example2::get_b() para a extensão VNDK libexample2_ext , você deve modificar o arquivo de cabeçalho existente e adicionar um #ifdef guarda:

#ifndef LIBEXAMPLE2_EXAMPLE_H_
#define LIBEXAMPLE2_EXAMPLE_H_

class Example2 {
 public:
  Example2();

  void get_a();

#ifdef LIBEXAMPLE2_ENABLE_VNDK_EXT
  void get_b();
#endif

 private:
  void *impl_;
};

#endif  // LIBEXAMPLE2_EXAMPLE_H_

A cc_defaults nomeados libexample2_ext_defaults é definida para os usuários de libexample2_ext :

cc_library {
    name: "libexample2",
    srcs: ["src/example2.cpp"],
    export_include_dirs: ["include"],
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libexample2_ext",
    srcs: ["src/example2.cpp"],
    export_include_dirs: ["include"],
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libexample2",
    },
    cflags: [
        "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1",
    ],
}

cc_defaults {
    name: "libexample2_ext_defaults",
    shared_libs: [
        "libexample2_ext",
    ],
    cflags: [
        "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1",
    ],
}

Os usuários de libexample2_ext pode incluir simplesmente libexample2_ext_defaults em sua defaults propriedade:

cc_binary {
    name: "example2_user_executable",
    defaults: ["libexample2_ext_defaults"],
    vendor: true,
}

Pacotes de produtos

No sistema de construção Android, as variáveis PRODUCT_PACKAGES especifica os executáveis, bibliotecas compartilhadas ou pacotes que devem ser instalados no dispositivo. As dependências transitivas dos módulos especificados também são instaladas implicitamente no dispositivo.

Se BOARD_VNDK_VERSION está habilitado, módulos com vendor_available ou vndk.enabled recebem tratamento especial. Se um módulo quadro depende de um módulo com vendor_available ou vndk.enabled , a variante do núcleo está incluído no conjunto de instalação transitiva. Se um módulo fornecedor depende de um módulo com vendor_available , a variante fornecedor está incluído no conjunto de instalação transitiva. No entanto, fornecedor variantes de módulos com vndk.enabled estão instalados ou não são usados por módulos de fornecedores.

Quando as dependências são invisíveis para o sistema de construção (por exemplo bibliotecas que podem ser abertas com compartilhada dlopen() em tempo de execução), você deve especificar os nomes dos módulos em PRODUCT_PACKAGES para instalar os módulos explicitamente.

Se um módulo tem vendor_available ou vndk.enabled , o nome do módulo está para sua variante do núcleo. Para especificar explicitamente a variante fornecedor no PRODUCT_PACKAGES , anexar um .vendor sufixo para o nome do módulo. Por exemplo:

cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
}

Neste exemplo, libexample significa /system/lib[64]/libexample.so e libexample.vendor significa /vendor/lib[64]/libexample.so . Para instalar /vendor/lib[64]/libexample.so , adicione libexample.vendor para PRODUCT_PACKAGES :

PRODUCT_PACKAGES += libexample.vendor