Comprendre les builds 64 bits

Le système de génération prend en charge la création de fichiers binaires pour deux architectures de processeur cible (64 bits et 32 ​​bits) dans la même version. C'est ce qu'on appelle une construction multilib .

Pour les bibliothèques statiques natives et les bibliothèques partagées, le système de construction définit des règles pour construire des binaires pour les deux architectures. La configuration du produit ( PRODUCT_PACKAGES ), ainsi que le graphique de dépendance, déterminent les fichiers binaires qui sont créés et installés sur l'image système.

Pour les exécutables et les applications, le système de construction ne construit que la version 64 bits par défaut, mais vous pouvez remplacer ce paramètre par une variable globale BoardConfig.mk ou une variable de portée de module.

Configuration du produit

BoardConfig.mk inclut les variables suivantes pour configurer la deuxième architecture CPU et ABI :

  • TARGET_2ND_ARCH
  • TARGET_2ND_ARCH_VARIANT
  • TARGET_2ND_CPU_VARIANT
  • TARGET_2ND_CPU_ABI
  • TARGET_2ND_CPU_ABI2

Vous pouvez voir un exemple dans build/target/board/generic_arm64/BoardConfig.mk .

Dans une construction multilib, les noms de module dans PRODUCT_PACKAGES couvrent à la fois les binaires 32 bits et 64 bits, tant qu'ils sont définis par le système de construction. Pour les bibliothèques extraites par dépendance, une bibliothèque 32 bits est installée uniquement si elle est requise par une autre bibliothèque 32 bits ou exécutable. Il en va de même pour les bibliothèques 64 bits.

Cependant, 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 construit uniquement la libc 64 bits. Pour construire la libc 32 bits, vous devez exécuter make libc_32 .

Définition du module dans Android.mk

Vous pouvez utiliser la variable LOCAL_MULTILIB pour configurer votre build pour 32 bits/64 bits et remplacer la variable globale TARGET_PREFER_32_BIT .

Définissez LOCAL_MULTILIB sur l'une des valeurs suivantes :

  • "both" construit à la fois 32 bits et 64 bits.
  • "32" ne construit que 32 bits.
  • "64" ne construit que 64 bits.
  • "first" construit uniquement pour la première architecture (32 bits dans les appareils 32 bits et 64 bits dans les appareils 64 bits).
  • "" est la valeur par défaut. Le système de construction décide quelle architecture construire en fonction de la classe du module et d'autres variables LOCAL_ , telles que LOCAL_MODULE_TARGET_ARCH et LOCAL_32_BIT_ONLY .

Si vous souhaitez construire votre module pour des architectures spécifiques, utilisez les variables suivantes :

  • LOCAL_MODULE_TARGET_ARCH
    Définissez cette variable sur une liste d'architectures, telles que arm x86 arm64 . Si l'architecture en cours de construction est dans cette liste, le module actuel est inclus par le système de construction.
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH
    Cette variable est l'opposé de LOCAL_MODULE_TARGET_ARCH . Si l'architecture en cours de construction n'est pas dans cette liste, le module actuel est inclus par le système de construction.

Il existe des variantes mineures de ces deux variables :

  • LOCAL_MODULE_TARGET_ARCH_WARN
  • LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH_WARN

Le système de construction avertit si le module actuel est ignoré en raison des architectures répertoriées.

Pour configurer des indicateurs de construction pour une architecture particulière, utilisez les variables LOCAL_ spécifiques à l'architecture. Une variable LOCAL_ spécifique à l'architecture est une variable LOCAL_ normale avec un suffixe d'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 construction pour cette architecture.

Parfois, il est plus facile de configurer des drapeaux selon que le binaire est actuellement construit pour 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,

Installation d'un chemin

Auparavant, vous pouviez utiliser LOCAL_MODULE_PATH pour installer une bibliothèque à un emplacement autre que celui par défaut. Par exemple, LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw .

Dans une version 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 à la fois 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 du fichier installé.
  • LOCAL_MODULE_PATH_32, LOCAL_MODULE_PATH_64
    Spécifie le chemin d'installation.

Sources générées

Dans une version multilib, si vous générez des fichiers source dans $(local-intermediates-dir) (ou $(intermediates-dir-for) avec des variables explicites), cela ne fonctionne pas de manière fiable. En effet, les sources générées intermédiaires sont requises à la fois par les versions 32 bits et 64 bits, mais $(local-intermediates-dir) pointe uniquement vers l'un des deux répertoires intermédiaires.

Le système de construction fournit un répertoire intermédiaire dédié, compatible avec plusieurs bibliothèques, pour générer des sources. Vous pouvez appeler $(local-generated-sources-dir) ou $(generated-sources-dir-for) pour obtenir le chemin du répertoire. Leurs utilisations sont similaires à $(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 construit à la fois pour 32 bits et 64 bits dans une version multilib.

Préconstruits

Dans une construction multilib, vous ne pouvez pas utiliser TARGET_ARCH (ou avec TARGET_2ND_ARCH ) pour indiquer au système de construction quelle architecture les cibles binaires prédéfinies. Utilisez plutôt les variables LOCAL_ LOCAL_MODULE_TARGET_ARCH ou LOCAL_MODULE_UNSUPPORTED_TARGET_ARCH .

Avec ces variables, le système de construction peut choisir le binaire préconstruit 32 bits correspondant même s'il travaille sur une construction multilib 64 bits.

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

Génération de fichiers ODEX

Pour les appareils 64 bits, nous générons 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, nous générons par défaut ODEX uniquement pour l'architecture 64 bits principale. Si une application doit être lancée à la fois dans les 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 possède des bibliothèques JNI 32 bits ou 64 bits, cet indicateur indique également au système de génération de les inclure.