Il sistema di build supporta la creazione di binari per due architetture CPU di destinazione (64 bit e 32 bit) nella stessa build. Questo è noto come build multilib .
Per le librerie statiche native e le librerie condivise, il sistema di compilazione imposta le regole per creare binari per entrambe le architetture. La configurazione del prodotto ( PRODUCT_PACKAGES
), insieme al grafico delle dipendenze, determina quali binari vengono compilati e installati nell'immagine di sistema.
Per eseguibili e app, il sistema di build crea solo la versione a 64 bit per impostazione predefinita, ma puoi sovrascrivere questa impostazione con una variabile BoardConfig.mk
globale o una variabile con ambito modulo.
Configurazione del prodotto
BoardConfig.mk
include le seguenti variabili per configurare la seconda architettura della CPU e l'ABI:
-
TARGET_2ND_ARCH
-
TARGET_2ND_ARCH_VARIANT
-
TARGET_2ND_CPU_VARIANT
-
TARGET_2ND_CPU_ABI
-
TARGET_2ND_CPU_ABI2
Puoi vedere un esempio in build/target/board/generic_arm64/BoardConfig.mk
.
In una build multilib, i nomi dei moduli in PRODUCT_PACKAGES
coprono sia i binari a 32 bit che a 64 bit, purché siano definiti dal sistema di build. Per le librerie inserite per dipendenza, viene installata una libreria a 32 bit solo se richiesta da un'altra libreria a 32 bit o eseguibile. Lo stesso vale per le librerie a 64 bit.
Tuttavia, i nomi dei moduli sulla riga di comando make
coprono solo la versione a 64 bit. Ad esempio, dopo aver eseguito lunch aosp_arm64-eng
, make libc
compila solo la libc a 64 bit. Per compilare la libc a 32 bit, è necessario eseguire make libc_32
.
Definizione del modulo in Android.mk
Puoi utilizzare la variabile LOCAL_MULTILIB
per configurare la tua build per 32 bit/64 bit e sovrascrivere la variabile globale TARGET_PREFER_32_BIT
.
Impostare LOCAL_MULTILIB
su uno dei seguenti:
-
"both"
costruisce sia 32 bit che 64 bit. -
"32"
costruisce solo 32 bit. -
"64"
costruisce solo 64 bit. -
"first"
viene compilato solo per la prima architettura (32 bit nei dispositivi a 32 bit e 64 bit nei dispositivi a 64 bit). -
""
è l'impostazione predefinita. Il sistema di compilazione decide quale architettura costruire in base alla classe del modulo e ad altre variabiliLOCAL_
, comeLOCAL_MODULE_TARGET_ARCH
eLOCAL_32_BIT_ONLY
.
Se vuoi costruire il tuo modulo per architetture specifiche, usa le seguenti variabili:
-
LOCAL_MODULE_TARGET_ARCH
Imposta questa variabile su un elenco di architetture, comearm x86 arm64
. Se l'architettura in costruzione è in quell'elenco, il modulo corrente è incluso nel sistema di compilazione. -
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
Questa variabile è l'opposto diLOCAL_MODULE_TARGET_ARCH
. Se l'architettura in costruzione non è in quell'elenco, il modulo corrente è incluso nel sistema di compilazione.
Esistono varianti minori di queste due variabili:
-
LOCAL_MODULE_TARGET_ARCH_WARN
-
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
Il sistema di compilazione avverte se il modulo corrente viene ignorato a causa delle architetture elencate.
Per impostare i flag di compilazione per una particolare architettura, utilizzare le variabili LOCAL_
specifiche dell'architettura. Una variabile LOCAL_
specifica per l'architettura è una normale variabile LOCAL_
con un suffisso per l'architettura, ad esempio:
-
LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
-
LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
-
LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,
Queste variabili vengono applicate solo se è in corso la creazione di un file binario per quell'architettura.
A volte è più semplice impostare i flag in base al fatto che il binario sia attualmente in fase di compilazione per 32 bit o 64 bit. Utilizzare la variabile LOCAL_
con un suffisso _32
o _64
, ad esempio:
-
LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
-
LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
-
LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,
Installazione di un percorso
In precedenza, era possibile utilizzare LOCAL_MODULE_PATH
per installare una libreria in una posizione diversa da quella predefinita. Ad esempio, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
.
In una build multilib, usa invece LOCAL_MODULE_RELATIVE_PATH
:
LOCAL_MODULE_RELATIVE_PATH := hw
Con questo formato, entrambe le librerie a 64 bit ea 32 bit vengono installate nella posizione corretta.
Se crei un eseguibile sia a 32 bit che a 64 bit, usa una delle seguenti variabili per distinguere il percorso di installazione:
-
LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64
Specifica il nome del file installato. -
LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
Specifica il percorso di installazione.
Fonti generate
In una build multilib, se generi file di origine in $(local-intermediates-dir)
(o $(intermediates-dir-for)
con variabili esplicite), non funziona in modo affidabile. Questo perché le origini generate intermedie sono richieste sia dalle build a 32 bit che a 64 bit, ma $(local-intermediates-dir)
punta solo a una delle due directory intermedie.
Il sistema di compilazione fornisce una directory intermedia dedicata, adatta a più librerie per la generazione di sorgenti. Puoi chiamare $(local-generated-sources-dir)
o $(generated-sources-dir-for)
per ottenere il percorso della directory. I loro usi sono simili a $(local-intermediates-dir)
e $(intermediates-dir-for)
.
Se un file sorgente viene generato in questa directory dedicata e prelevato da LOCAL_GENERATED_SOURCES
, viene compilato sia per 32 bit che per 64 bit in una build multilib.
Precostruiti
In una build multilib, non puoi usare TARGET_ARCH
(o insieme a TARGET_2ND_ARCH
) per dire al sistema di build quale architettura è destinata al binario predefinito. Utilizzare invece le variabili LOCAL_
LOCAL_MODULE_TARGET_ARCH
o LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
Con queste variabili, il sistema di build può scegliere il corrispondente binario precompilato a 32 bit anche se sta lavorando su una build multilib a 64 bit.
Se desideri utilizzare l'architettura scelta per calcolare il percorso di origine per il file binario predefinito, chiama $(get-prebuilt-src-arch)
.
Generazione di file ODEX
Per i dispositivi a 64 bit, per impostazione predefinita, generiamo file ODEX a 32 e 64 bit per l'immagine di avvio e le eventuali librerie Java. Per gli APK, per impostazione predefinita, generiamo ODEX solo per l'architettura primaria a 64 bit. Se un'app verrà avviata in entrambi i processi a 32 bit e 64 bit, utilizzare LOCAL_MULTILIB := both
per assicurarsi che vengano generati file ODEX a 32 bit e 64 bit. Se l'app ha librerie JNI a 32 o 64 bit, quel flag indica anche al sistema di compilazione di includerle.