Créer des builds pour les architectures 32 bits et 64 bits

Le système de compilation permet de créer 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 multilib build.

Pour les bibliothèques statiques intégrées et les bibliothèques partagées, le système de compilation configure des règles pour créer des binaires pour les deux architectures. Configuration du produit (PRODUCT_PACKAGES), ainsi que le graphique des dépendances, déterminent les binaires sont créés et installés sur l’image système.

Pour les exécutables et les applications, le système de compilation ne compile que la version 64 bits en par défaut, mais vous pouvez remplacer ce paramètre par une règle la variable BoardConfig.mk ou une variable à l'échelle d'un module.

Identifier une deuxième architecture de processeur et une 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 qui utilise ces variables, consultez build/make/target/board/generic_arm64/BoardConfig.mk

Dans une compilation multilib, les noms de module dans PRODUCT_PACKAGES couvrent à la fois 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 exécutable 32 bits ou 64 bits.

Toutefois, les noms de module sur la ligne de commande make ne couvrent que la version 64 bits. Par exemple, après avoir exécuté lunch aosp_arm64-eng, make libc ne crée que la bibliothèque 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 TARGET_PREFER_32_BIT globale.

Pour remplacer TARGET_PREFER_32_BIT, définissez LOCAL_MULTILIB sur l'une des valeurs suivantes :

  • both génère des builds 32 bits et 64 bits.
  • 32 ne crée que des builds 32 bits.
  • 64 ne crée que des versions 64 bits.
  • first ne compile 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 choisit une architecture basée sur la classe du module et sur d'autres Variables LOCAL_*, telles que LOCAL_MODULE_TARGET_ARCH et LOCAL_32_BIT_ONLY.

Si vous souhaitez créer votre module pour des architectures spécifiques, utilisez variables:

  • LOCAL_MODULE_TARGET_ARCH : définissez cette variable sur une liste d'architectures. comme arm x86 arm64. Si l'architecture en cours de construction 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é de LOCAL_MODULE_TARGET_ARCH. Si l'architecture en cours de compilation est not 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 vous avertit si le module actuel est ignoré en raison de l'erreur d'architectures répertoriées.

Pour configurer des indicateurs de compilation pour une architecture particulière, utilisez la 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 créé pour cette de l'architecture.

Il est parfois plus simple de configurer des indicateurs en fonction de la version binaire créée (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 vers un emplacement autre que celui 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 endroit.

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 les appareils nom de fichier.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64 : spécifie le chemin d'installation.

Obtenir le répertoire intermédiaire des fichiers sources

Dans une compilation multilib, si vous générez des fichiers sources $(local-intermediates-dir) (ou $(intermediates-dir-for)) avec des variables explicites), elle ne fonctionne pas de manière fiable. C'est car les sources intermédiaires générées sont requises par les instances Builds 64 bits, mais $(local-intermediates-dir) ne pointe vers qu'une des versions les deux répertoires intermédiaires.

Le système de compilation fournit un répertoire intermédiaire dédié, compatible avec les multilibs, pour générer des sources. Pour récupérer le chemin d'accès du répertoire intermédiaire, utilisez la macro $(local-generated-sources-dir) ou $(generated-sources-dir-for). Le fonctionnement de ces macros est semblable $(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 conçu pour les versions 32 bits et 64 bits dans un build 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

Avec ces variables, le système de compilation peut choisir la version 32 bits binaire prédéfini même s'il travaille sur un build multilib 64 bits.

Si vous souhaitez utiliser l'architecture choisie pour calculer le chemin d'accès source du binaire précompilé, appelez $(get-prebuilt-src-arch).

Assurer la génération de fichiers ODEX 32 et 64 bits

Pour les appareils 64 bits, Google génère par défaut des messages ODEX 32 bits et 64 bits. pour l'image de démarrage et les bibliothèques Java. Pour les APK, Google ne génère par défaut des fichiers ODEX que pour l'architecture 64 bits principale. Si une application est lancée à la fois 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 contient des bibliothèques JNI 32 ou 64 bits, cet indicateur indique également au système de compilation de les inclure.