O sistema de build permite a criação de binários para duas arquiteturas de CPU de destino de 32 e 64 bits no mesmo build. Esse build de dois destinos é conhecido como versão multilib.
Para bibliotecas estáticas integradas e bibliotecas compartilhadas, o sistema de build configura
regras para criar binários para as duas arquiteturas. A configuração do produto (PRODUCT_PACKAGES
),
junto com o gráfico de dependência, determina quais
binários são criados e instalados na imagem do sistema.
Para executáveis e apps, o sistema de build cria apenas a versão de 64 bits por
padrão, mas é possível substituir essa configuração usando uma variável global BoardConfig.mk
ou uma variável com escopo de módulo.
Identificar uma segunda arquitetura de CPU e ABI
O BoardConfig.mk
inclui as seguintes variáveis para configurar a segunda arquitetura de
CPU e interface binária do aplicativo (ABI):
TARGET_2ND_ARCH
TARGET_2ND_ARCH_VARIANT
TARGET_2ND_CPU_VARIANT
TARGET_2ND_CPU_ABI
TARGET_2ND_CPU_ABI2
Para conferir um exemplo de makefile que usa essas variáveis, consulte
build/make/target/board/generic_arm64/BoardConfig.mk
.
Em um build multilib, os nomes dos módulos em PRODUCT_PACKAGES
abrangem
os binários de 32 e 64 bits, desde que eles sejam definidos pelo sistema
de build. Para bibliotecas incluídas por dependência, uma biblioteca de 32 ou 64 bits é
instalada somente se for exigida por outra biblioteca de 32 ou 64 bits ou
executável.
No entanto, os nomes dos módulos na linha de comando make
abrangem apenas a
versão de 64 bits. Por exemplo, após executar lunch aosp_arm64-eng
, make libc
cria somente a libc de 64 bits. Para
criar a libc de 32 bits, é necessário executar make libc_32
.
Definir a arquitetura com módulos em Android.mk
Você pode usar a variável LOCAL_MULTILIB
para configurar seu build
para 32 e 64 bits e substituir a variável TARGET_PREFER_32_BIT
global.
Para substituir TARGET_PREFER_32_BIT
, defina LOCAL_MULTILIB
como um dos
seguintes:
both
cria 32 bits e 64 bits.32
cria apenas 32 bits.64
cria apenas 64 bits.first
cria apenas para a primeira arquitetura (32 bits em dispositivos de 32 bits e 64 bits em dispositivos de 64 bits).
Por padrão, o LOCAL_MULTILIB
não está definido, e o sistema de build decide qual
arquitetura criar 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 criar seu módulo para arquiteturas específicas, use as seguintes variáveis:
LOCAL_MODULE_TARGET_ARCH
: define essa variável como uma lista de arquiteturas, comoarm x86 arm64
. Se a arquitetura que está sendo criada estiver nessa lista, o módulo atual será incluído pelo sistema de build.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
: essa variável é o oposto deLOCAL_MODULE_TARGET_ARCH
. Se a arquitetura que está sendo criadanot
(não) estiver nessa lista, o módulo atual será incluído pelo sistema de build.
Existem variantes menores dessas duas variáveis:
LOCAL_MODULE_TARGET_ARCH_WARN
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
O sistema de build vai avisar se o módulo atual for ignorado por causa das arquiteturas listadas.
Para configurar flags de criação para uma arquitetura específica, use as
variáveis LOCAL_*
específicas da arquitetura, em que
*
é 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 criado para essa arquitetura.
Às vezes, é mais fácil configurar flags de acordo com a
criação do binário atual 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 o caminho de instalação da biblioteca
Para um build 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 um build multilib, use LOCAL_MODULE_RELATIVE_PATH
:
LOCAL_MODULE_RELATIVE_PATH := hw
Com esse formato, as bibliotecas de 32 e 64 bits são instaladas no local correto.
Se você criar um executável como 32 bits e 64 bits, use uma das seguintes variáveis para diferenciar 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.
Conseguir o diretório intermediário para arquivos de origem
Em um build multilib, se você gerar arquivos de origem para
$(local-intermediates-dir)
(ou $(intermediates-dir-for)
com variáveis explícitas), ele não vai funcionar de forma confiável. Isso
ocorre porque as origens intermediárias geradas são exigidas pelas versões de 32 e
64 bits, mas $(local-intermediates-dir)
aponta apenas para um dos
dois diretórios intermediários.
O sistema de build fornece um diretório intermediário dedicado e compatível com multilib
para gerar origens. Para recuperar o caminho intermediário
do diretório, use a macro
$(local-generated-sources-dir)
ou
$(generated-sources-dir-for)
. O uso dessas macros é parecido com
$(local-intermediates-dir)
e $(intermediates-dir-for)
.
Se um arquivo de origem for gerado para esse diretório dedicado e escolhido
por LOCAL_GENERATED_SOURCES
, ele será criado para 32 bits e 64 bits
em um build multilib.
Indicar a arquitetura do sistema de alvos binários pré-criados
Em um build multilib, não é possível usar TARGET_ARCH
, ou TARGET_ARCH
com
TARGET_2ND_ARCH
, para indicar a arquitetura do sistema de
de alvos binários pré-criados. 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 build pode escolher o binário pré-criado de 32 bits correspondente, mesmo que esteja criando um build multilib de 64 bits.
Se você quiser usar a arquitetura escolhida para calcular o caminho de origem do
binário pré-criado, chame $(get-prebuilt-src-arch)
.
Garantir a geração de arquivos ODEX de 32 e 64 bits
Por padrão, para dispositivos de 64 bits, o Google gera arquivos ODEX de 32 e 64 bits
para a imagem de inicialização e as bibliotecas Java. Para os APKs, por padrão, o Google
gera o ODEX apenas para a arquitetura principal de 64 bits. Se um app for iniciado
em processos de 32 e 64 bits, use LOCAL_MULTILIB := both
para garantir
que os arquivos ODEX de 32 e de 64 bits sejam gerados. Caso o app tenha alguma biblioteca JNI de 32
ou 64 bits, essa flag também instrui o sistema de build a incluí-las.