Le système de compilation permet de compiler des binaires pour deux architectures de processeur cibles, 32 bits et 64 bits, dans la même compilation. Cette compilation à deux cibles est appelée compilation multilib.
Pour les bibliothèques statiques et partagées intégrées, le système de compilation configure des règles permettant de compiler des binaires pour les deux architectures. La configuration du produit (PRODUCT_PACKAGES
), ainsi que le graphique des dépendances, déterminent les binaires qui sont compilés et installés dans l'image système.
Pour les exécutables et les applications, le système de compilation ne crée que la version 64 bits par défaut, mais vous pouvez remplacer ce paramètre par une variable BoardConfig.mk
globale ou une variable à portée de module.
Identifier une deuxième architecture de processeur et un deuxième ABI
BoardConfig.mk
inclut les variables suivantes pour configurer la deuxième architecture de processeur et l'interface binaire d'application (ABI) :
TARGET_2ND_ARCH
TARGET_2ND_ARCH_VARIANT
TARGET_2ND_CPU_VARIANT
TARGET_2ND_CPU_ABI
TARGET_2ND_CPU_ABI2
Pour obtenir un exemple de fichier makefile utilisant ces variables, consultez build/make/target/board/generic_arm64/BoardConfig.mk
.
Dans une compilation multilib, les noms de modules dans PRODUCT_PACKAGES
couvrent les binaires 32 bits et 64 bits, à condition qu'ils soient définis par le système de compilation. Pour les bibliothèques incluses par dépendance, une bibliothèque 32 bits ou 64 bits n'est installée que si elle est requise par une autre bibliothèque ou un autre exécutable 32 bits ou 64 bits.
Toutefois, les noms de modules sur la ligne de commande make
ne couvrent que la version 64 bits. Par exemple, après l'exécution de lunch aosp_arm64-eng
, make libc
ne compile que la libc 64 bits. Pour compiler la libc 32 bits, vous devez exécuter make libc_32
.
Définir l'architecture du module dans Android.mk
Vous pouvez utiliser la variable LOCAL_MULTILIB
pour configurer votre compilation pour 32 bits et 64 bits, et remplacer la variable globale TARGET_PREFER_32_BIT
.
Pour remplacer TARGET_PREFER_32_BIT
, définissez LOCAL_MULTILIB
sur l'une des valeurs suivantes :
both
crée des versions 32 bits et 64 bits.32
ne compile que les versions 32 bits.64
ne génère que des versions 64 bits.first
ne crée que pour la première architecture (32 bits sur les appareils 32 bits et 64 bits sur les appareils 64 bits).
Par défaut, LOCAL_MULTILIB
n'est pas défini et le système de compilation décide quelle architecture compiler en fonction de la classe de module et d'autres variables LOCAL_*
, telles que LOCAL_MODULE_TARGET_ARCH
et LOCAL_32_BIT_ONLY
.
Si vous souhaitez compiler votre module pour des architectures spécifiques, utilisez les variables suivantes :
LOCAL_MODULE_TARGET_ARCH
: définissez cette variable sur une liste d'architectures, commearm x86 arm64
. Si l'architecture en cours de compilation figure dans cette liste, le module actuel est inclus par le système de compilation.LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
: cette variable est l'opposé deLOCAL_MODULE_TARGET_ARCH
. Si l'architecture en cours de compilation estnot
dans cette liste, le module actuel est inclus par le système de compilation.
Il existe des variantes mineures de ces deux variables :
LOCAL_MODULE_TARGET_ARCH_WARN
LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN
Le système de compilation émet un avertissement si le module actuel est ignoré en raison des architectures listées.
Pour configurer des indicateurs de compilation pour une architecture particulière, utilisez les variables LOCAL_*
spécifiques à l'architecture, où *
est un suffixe spécifique à l'architecture. Par exemple :
LOCAL_SRC_FILES_arm, LOCAL_SRC_FILES_x86,
LOCAL_CFLAGS_arm, LOCAL_CFLAGS_arm64,
LOCAL_LDFLAGS_arm, LOCAL_LDFLAGS_arm64,
Ces variables ne sont appliquées que si un binaire est en cours de compilation pour cette architecture.
Il est parfois plus facile de configurer des indicateurs en fonction de l'architecture du binaire (32 bits ou 64 bits). Utilisez la variable LOCAL_*
avec un suffixe _32
ou _64
, par exemple :
LOCAL_SRC_FILES_32, LOCAL_SRC_FILES_64,
LOCAL_CFLAGS_32, LOCAL_CFLAGS_64,
LOCAL_LDFLAGS_32, LOCAL_LDFLAGS_64,
Définir le chemin d'installation de la bibliothèque
Pour une compilation non multilib, vous pouvez utiliser LOCAL_MODULE_PATH
pour installer une bibliothèque à un emplacement autre que l'emplacement par défaut. Par exemple, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw
.
Toutefois, dans une compilation multilib, utilisez plutôt LOCAL_MODULE_RELATIVE_PATH
:
LOCAL_MODULE_RELATIVE_PATH := hw
Avec ce format, les bibliothèques 64 bits et 32 bits sont installées au bon emplacement.
Si vous créez un exécutable en 32 bits et en 64 bits, utilisez l'une des variables suivantes pour distinguer le chemin d'installation :
LOCAL_MODULE_STEM_32, LOCAL_MODULE_STEM_64
: spécifie le nom de fichier installé.LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
: spécifie le chemin d'installation.
Obtenir le répertoire intermédiaire pour les fichiers sources
Dans une compilation multilib, si vous générez des fichiers sources vers $(local-intermediates-dir)
(ou $(intermediates-dir-for)
avec des variables explicites), cela ne fonctionne pas de manière fiable. En effet, les sources intermédiaires générées sont requises par les builds 32 bits et 64 bits, mais $(local-intermediates-dir)
ne pointe que vers l'un des deux répertoires intermédiaires.
Le système de compilation fournit un répertoire intermédiaire dédié et compatible avec multilib pour générer des sources. Pour récupérer le chemin d'accès au répertoire intermédiaire, utilisez la macro $(local-generated-sources-dir)
ou $(generated-sources-dir-for)
. L'utilisation de ces macros est semblable à celle de $(local-intermediates-dir)
et $(intermediates-dir-for)
.
Si un fichier source est généré dans ce répertoire dédié et récupéré par LOCAL_GENERATED_SOURCES
, il est compilé pour les architectures 32 bits et 64 bits dans une compilation multilib.
Indiquer l'architecture système des cibles binaires précompilées
Dans une compilation multilib, vous ne pouvez pas utiliser TARGET_ARCH
ni TARGET_ARCH
combiné à TARGET_2ND_ARCH
pour indiquer l'architecture système des cibles binaires précompilées. Utilisez plutôt les variables LOCAL_*
LOCAL_MODULE_TARGET_ARCH
ou LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
.
Grâce à ces variables, le système de compilation peut choisir le binaire précompilé 32 bits correspondant, même s'il fonctionne sur une compilation multilib 64 bits.
Si vous souhaitez utiliser l'architecture choisie pour calculer le chemin source du binaire précompilé, appelez $(get-prebuilt-src-arch)
.
Génération de fichiers ODEX 32 et 64 bits
Pour les appareils 64 bits, Google génère par défaut des fichiers ODEX 32 bits et 64 bits pour l'image de démarrage et toutes les bibliothèques Java. Pour les APK, par défaut, Google ne génère ODEX que pour l'architecture 64 bits principale. Si une application est lancée dans des processus 32 bits et 64 bits, utilisez LOCAL_MULTILIB := both
pour vous assurer que les fichiers ODEX 32 bits et 64 bits sont générés. Si l'application comporte des bibliothèques JNI 32 bits ou 64 bits, cet indicateur indique également au système de compilation de les inclure.