Crie para arquiteturas de 32 e 64 bits

O sistema de compilação oferece suporte à construção de binários para duas arquiteturas de CPU de destino, 32 bits e 64 bits, na mesma compilação. Essa compilação de dois destinos é conhecida como compilação multilib .

Para bibliotecas estáticas integradas e bibliotecas compartilhadas, o sistema de construção configura regras para construir binários para ambas as arquiteturas. A configuração do produto ( PRODUCT_PACKAGES ), juntamente com o gráfico de dependência, determina quais binários são compilados e instalados na imagem do sistema.

Para executáveis ​​e aplicativos, o sistema de compilação cria apenas a versão de 64 bits por padrão, mas você pode substituir essa configuração por uma variável global BoardConfig.mk ou uma variável com escopo de módulo.

Identifique uma segunda arquitetura de CPU e ABI

BoardConfig.mk inclui as seguintes variáveis ​​para configurar a segunda arquitetura de CPU e interface binária de aplicativo (ABI):

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Para obter um exemplo de makefile que usa essas variáveis, consulte build/make/target/board/generic_arm64/BoardConfig.mk .

Em uma compilação multilib, os nomes dos módulos em PRODUCT_PACKAGES abrangem os binários de 32 e 64 bits, desde que sejam definidos pelo sistema de compilação. Para bibliotecas incluídas por dependência, uma biblioteca de 32 ou 64 bits será instalada somente se for exigida por outra biblioteca ou executável de 32 ou 64 bits.

No entanto, os nomes dos módulos na linha de comando make abrangem apenas a versão de 64 bits. Por exemplo, depois de executar lunch aosp_arm64-eng , make libc construa apenas a libc de 64 bits. Para construir a libc de 32 bits, você precisa executar make libc_32 .

Defina a arquitetura do módulo em Android.mk

Você pode usar a variável LOCAL_MULTILIB para configurar sua construção para 32 bits e 64 bits e substituir a variável global TARGET_PREFER_32_BIT .

Para substituir TARGET_PREFER_32_BIT , configure LOCAL_MULTILIB como um dos seguintes:

  • both compilam 32 e 64 bits.
  • 32 compila apenas 32 bits.
  • 64 compila apenas 64 bits.
  • first compilações apenas para a primeira arquitetura (32 bits em dispositivos de 32 bits e 64 bits em dispositivos de 64 bits).

Por padrão, LOCAL_MULTILIB não está definido e o sistema de construção decide qual arquitetura construir com base na classe do módulo e outras variáveis LOCAL_ * , como LOCAL_MODULE_TARGET_ARCH e LOCAL_32_BIT_ONLY .

Se você quiser construir seu módulo para arquiteturas específicas, use as seguintes variáveis:

  • LOCAL_MODULE_TARGET_ARCH - Defina esta variável para uma lista de arquiteturas, como arm x86 arm64 . Se a arquitetura que está sendo construída estiver nessa lista, o módulo atual será incluído pelo sistema de construção.

  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH - Esta variável é o oposto de LOCAL_MODULE_TARGET_ARCH . Se a arquitetura que está sendo construída not estiver nessa lista, o módulo atual será incluído pelo sistema de construção.

Existem variantes menores dessas duas variáveis:

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

O sistema de compilação avisa se o módulo atual for ignorado devido às arquiteturas listadas.

Para configurar sinalizadores de construção para uma arquitetura específica, use as variáveis LOCAL_ * específicas da arquitetura, onde * é um sufixo específico da arquitetura, por exemplo:

  • LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
  • LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
  • LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,

Essas variáveis ​​serão aplicadas somente se um binário estiver sendo construído para aquela arquitetura.

Às vezes é mais fácil configurar sinalizadores com base no fato de o binário estar sendo compilado para 32 ou 64 bits. Use a variável LOCAL_ * com um sufixo _32 ou _64 , por exemplo:

  • LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
  • LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
  • LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,

Definir caminho de instalação da biblioteca

Para uma construção não multilib, você pode usar LOCAL_MODULE_PATH para instalar uma biblioteca em um local diferente do padrão. Por exemplo, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw .

No entanto, em uma construção multilib, use LOCAL_MODULE_RELATIVE_PATH :

LOCAL_MODULE_RELATIVE_PATH := hw

Com esse formato, as bibliotecas de 64 e 32 bits são instaladas no local correto.

Se você criar um executável de 32 e 64 bits, use uma das seguintes variáveis ​​para distinguir o caminho de instalação:

  • LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64 - Especifica o nome do arquivo instalado.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 – Especifica o caminho de instalação.

Obtenha o diretório intermediário para arquivos de origem

Em uma compilação multilib, se você gerar arquivos de origem para $(local-intermediates-dir) (ou $(intermediates-dir-for) com variáveis ​​explícitas), ele não funcionará de maneira confiável. Isso ocorre porque as fontes intermediárias geradas são exigidas pelas compilações de 32 e 64 bits, mas $(local-intermediates-dir) aponta para apenas um dos dois diretórios intermediários.

O sistema de compilação fornece um diretório intermediário dedicado e compatível com multilib para gerar fontes. Para recuperar o caminho do diretório intermediário, use a macro $(local-generated-sources-dir) ou $(generated-sources-dir-for) . Os usos dessas macros são semelhantes a $(local-intermediates-dir) e $(intermediates-dir-for) .

Se um arquivo de origem for gerado neste diretório dedicado e obtido por LOCAL_GENERATED_SOURCES , ele será compilado para 32 e 64 bits em uma compilação multilib.

Indique a arquitetura do sistema de alvos binários pré-construídos

Em uma construção multilib, você não pode usar TARGET_ARCH ou TARGET_ARCH combinado com TARGET_2ND_ARCH , para indicar a arquitetura do sistema dos destinos binários pré-construídos. Em vez disso, use as variáveis LOCAL_ * LOCAL_MODULE_TARGET_ARCH ou LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH .

Com essas variáveis, o sistema de compilação pode escolher o binário pré-construído correspondente de 32 bits, mesmo se estiver trabalhando em uma compilação multilib de 64 bits.

Se você quiser usar a arquitetura escolhida para calcular o caminho de origem do binário pré-construído, chame $(get-prebuilt-src-arch) .

Garanta a geração de arquivos ODEX de 32 e 64 bits

Para dispositivos de 64 bits, por padrão, o Google gera arquivos ODEX de 32 e 64 bits para a imagem de inicialização e quaisquer bibliotecas Java. Para APKs, por padrão, o Google gera ODEX apenas para a arquitetura primária de 64 bits. Se um aplicativo for iniciado em processos de 32 e 64 bits, use LOCAL_MULTILIB := both para garantir que os arquivos ODEX de 32 e 64 bits sejam gerados. Se o aplicativo tiver bibliotecas JNI de 32 ou 64 bits, esse sinalizador também informará ao sistema de compilação para incluí-las.