Android.mk

Cette page décrit la syntaxe du fichier de compilation Android.mk utilisé par ndk-build.

Présentation

Le fichier Android.mk se trouve dans un sous-répertoire du répertoire jni/ de votre projet. Il décrit les sources et les bibliothèques partagées au système de compilation. Il s'agit d'un minuscule fragment de fichier GNU makefile que le système de compilation analyse une ou plusieurs fois. Le fichier Android.mk sert à définir les paramètres à l'échelle du projet qu'Application.mk, que le système de compilation et que vos variables d'environnement n'ont pas définies. Il peut également remplacer les paramètres à l'échelle du projet pour des modules spécifiques.

La syntaxe d'Android.mk vous permet de regrouper vos sources dans des modules. Un module est soit une bibliothèque statique, soit une bibliothèque partagée, soit un exécutable autonome. Vous pouvez définir un ou plusieurs modules dans chaque fichier Android.mk et utiliser le même fichier source dans plusieurs modules. Le système de compilation ne place que les bibliothèques partagées dans le package d'application. En outre, les bibliothèques statiques peuvent générer des bibliothèques partagées.

En plus d'empaqueter des bibliothèques, le système de compilation gère plusieurs autres éléments pour vous. Par exemple, vous n'avez pas besoin d'indiquer dans le fichier Android.mk les fichiers d'en-tête ni les dépendances explicites entre les fichiers générés. Le système de compilation du NDK calcule ces relations automatiquement. Par conséquent, vous devriez pouvoir bénéficier de la compatibilité avec les nouvelles chaînes d'outils ou de plates-formes dans les prochaines versions du NDK sans avoir à toucher au fichier Android.mk.

La syntaxe de ce fichier est très proche de celle utilisée dans les fichiers Android.mk distribués avec le projet Open Source Android complet. Bien que la mise en œuvre du système de compilation qui les utilise soit différente, leur similarité est un choix de conception intentionnel visant à faciliter la réutilisation du code source pour les bibliothèques externes par les développeurs d'applications.

Principes de base

Avant d'explorer la syntaxe en détail, il est utile de commencer par se familiariser avec les principes de base d'un fichier Android.mk. Cette section utilise le fichier Android.mk de l'exemple Hello-JNI dans cet objectif, en expliquant le rôle de chaque ligne du fichier.

Un fichier Android.mk doit commencer par définir la variable LOCAL_PATH :

LOCAL_PATH := $(call my-dir)

Cette variable indique l'emplacement des fichiers sources dans l'arborescence de développement. Ici, la fonction de macro my-dir, fournie par le système de compilation, renvoie le chemin du répertoire actuel (le répertoire contenant le fichier Android.mk lui-même).

La ligne suivante déclare la variable CLEAR_VARS, dont la valeur est fournie par le système de compilation.

include $(CLEAR_VARS)

La variable CLEAR_VARS renvoie vers un fichier GNU makefile qui efface de nombreuses variables LOCAL_XXX, telles que LOCAL_MODULE, LOCAL_SRC_FILES et LOCAL_STATIC_LIBRARIES. Notez qu'il n'efface pas LOCAL_PATH. Cette variable doit conserver sa valeur, car le système analyse tous les fichiers de contrôle de compilation dans un seul contexte d'exécution GNU Make où toutes les variables sont globales. Vous devez (re)déclarer cette variable avant de décrire chaque module.

Ensuite, la variable LOCAL_MODULE stocke le nom du module que vous souhaitez compiler. Utilisez cette variable une fois par module dans votre application.

LOCAL_MODULE := hello-jni

Le nom de chaque module doit être unique et ne contenir aucun espace. Lorsqu'il génère le fichier final de la bibliothèque partagée, le système de compilation ajoute automatiquement le préfixe et le suffixe appropriés au nom que vous attribuez à LOCAL_MODULE. L'exemple ci-dessus génère une bibliothèque appelée libhello-jni.so.

La ligne suivante énumère les fichiers sources, en séparant plusieurs fichiers par un espace :

LOCAL_SRC_FILES := hello-jni.c

La variable LOCAL_SRC_FILES doit contenir une liste de fichiers sources C et/ou C++ à compiler dans un module.

La dernière ligne permet au système de tout relier :

include $(BUILD_SHARED_LIBRARY)

La variable BUILD_SHARED_LIBRARY pointe vers un script GNU makefile qui collecte toutes les informations que vous avez définies dans les variables LOCAL_XXX depuis le dernier attribut include. Ce script détermine les éléments à créer et comment procéder.

Vous pouvez consulter des exemples plus complexes dans les répertoires d'exemples, dont les fichiers Android.mk sont accompagnés de commentaires. De plus, la section Exemple : activité native offre une explication détaillée du fichier Android.mk de cet exemple. Enfin, la section Variables et macros fournit des informations supplémentaires sur les variables de cette section.

Variables et macros

Le système de compilation fournit de nombreuses variables possibles dans le fichier Android.mk. Un grand nombre d'entre elles sont associées à des valeurs préattribuées. D'autres sont attribuées par vos soins.

En outre, vous pouvez également définir des variables arbitraires. Dans ce cas, n'oubliez pas que le système de compilation du NDK réserve les noms de variables suivants :

  • Les noms commençant par LOCAL_, comme LOCAL_MODULE
  • Les noms commençant par PRIVATE_, NDK_ ou APP (le système de compilation les utilise en interne)
  • Les noms en minuscules, comme my-dir (le système de compilation les utilise également en interne)

Si vous devez définir vos propres variables de commodité dans un fichier Android.mk, nous vous recommandons de faire précéder leur nom de MY_.

Variables d'inclusion définies par le NDK

Cette section traite des variables GNU Make définies par le système de compilation avant d'analyser votre fichier Android.mk. Dans certains cas, le NDK peut analyser le fichier Android.mk plusieurs fois, en utilisant une définition différente pour certaines de ces variables à chaque fois.

CLEAR_VARS

Cette variable renvoie vers un script de compilation qui annule la définition de presque toutes les variables LOCAL_XXX répertoriées dans la section "Variables définies par le développeur" ci-dessous. Utilisez cette variable pour inclure ce script avant de décrire un nouveau module. Dans ce cas, la syntaxe est la suivante :

include $(CLEAR_VARS)

BUILD_EXECUTABLE

Cette variable renvoie vers un script de compilation qui collecte toutes les informations sur le module que vous avez fourni dans les variables LOCAL_XXX et détermine comment compiler un fichier exécutable cible à partir des sources que vous avez indiquées. Notez que pour utiliser ce script, vous devez au moins avoir attribué des valeurs aux éléments LOCAL_MODULE et LOCAL_SRC_FILES. Pour en savoir plus sur ces variables, consultez la section Variables de description de module.

La syntaxe d'utilisation de cette variable est la suivante :

include $(BUILD_EXECUTABLE)

BUILD_SHARED_LIBRARY

Cette variable renvoie vers un script de compilation qui collecte toutes les informations sur le module que vous avez fourni dans les variables LOCAL_XXX et détermine comment compiler une bibliothèque partagée cible à partir des sources que vous avez indiquées. Notez que pour utiliser ce script, vous devez au moins avoir attribué des valeurs aux éléments LOCAL_MODULE et LOCAL_SRC_FILES. Pour en savoir plus sur ces variables, consultez la section Variables de description de module.

La syntaxe d'utilisation de cette variable est la suivante :

include $(BUILD_SHARED_LIBRARY)

Une variable de bibliothèque partagée amène le système de compilation à générer un fichier de bibliothèque avec une extension .so.

BUILD_STATIC_LIBRARY

Variante de BUILD_SHARED_LIBRARY utilisée pour créer une bibliothèque statique. Le système de compilation ne copie pas les bibliothèques statiques dans le projet/package, mais peut les utiliser pour créer des bibliothèques partagées (voir LOCAL_STATIC_LIBRARIES et LOCAL_WHOLE_STATIC_LIBRARIES, ci-dessous). La syntaxe d'utilisation de cette variable est la suivante :

include $(BUILD_STATIC_LIBRARY)

Une variable de bibliothèque statique amène le système de compilation à générer une bibliothèque avec une extension .a.

PREBUILT_SHARED_LIBRARY

Renvoie vers un script de compilation permettant de spécifier une bibliothèque partagée prédéfinie. Contrairement aux cas BUILD_SHARED_LIBRARY et BUILD_STATIC_LIBRARY, ici la valeur de LOCAL_SRC_FILES ne peut pas être un fichier source. Il doit s'agir d'un seul chemin d'accès à une bibliothèque partagée prédéfinie, comme foo/libfoo.so. La syntaxe d'utilisation de cette variable est la suivante :

include $(PREBUILT_SHARED_LIBRARY)

Vous pouvez également référencer une bibliothèque prédéfinie dans un autre module à l'aide de la variable LOCAL_PREBUILTS. Pour en savoir plus sur l'utilisation des bibliothèques prédéfinies, consultez la section Utiliser des bibliothèques prédéfinies.

PREBUILT_STATIC_LIBRARY

Identique à PREBUILT_SHARED_LIBRARY, mais pour une bibliothèque statique prédéfinie. Pour en savoir plus sur l'utilisation des bibliothèques prédéfinies, consultez la section Utiliser des bibliothèques prédéfinies.

Variables d'informations cibles

Le système de compilation analyse Android.mk une fois par ABI spécifié par la variable APP_ABI, ce qui est généralement défini dans le fichier Application.mk. Si APP_ABI est défini sur all, le système de compilation analyse Android.mk une fois par ABI compatible avec le NDK. Cette section décrit les variables que le système de compilation définit à chaque fois qu'il analyse Android.mk.

TARGET_ARCH

Gamme de processeurs ciblée par le système de compilation lorsqu'il analyse ce fichier Android.mk. Cette variable est l'une des suivantes : arm, arm64, x86 ou x86_64.

TARGET_PLATFORM

Numéro de niveau d'API Android ciblé par le système de compilation lorsqu'il analyse ce fichier Android.mk. Par exemple, les images système Android 5.1 correspondent au niveau d'API Android 22 : android-22. Pour obtenir la liste complète des noms de plates-formes et des images système Android correspondantes, consultez la section API natives. L'exemple suivant montre la syntaxe à utiliser pour cette variable :

ifeq ($(TARGET_PLATFORM),android-22)
    # ... do something ...
endif

TARGET_ARCH_ABI

ABI ciblé par le système de compilation lorsqu'il analyse ce fichier Android.mk. Le tableau 1 indique le paramètre d'ABI utilisé pour chaque architecture et processeur compatibles.

Tableau 1. Paramètres ABI pour différents processeurs et architectures

Processeur et architecture Paramètre
ARMv7 armeabi-v7a
ARMv8 AArch64 arm64-v8a
i686 x86
x86-64 x86_64

L'exemple suivant montre comment vérifier qu'ARMv8 AArch64 est la combinaison processeur/ABI cible :

ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
  # ... do something ...
endif

Pour en savoir plus sur les ABI d'architecture et les problèmes de compatibilité associés, consultez la section ABI Android.

Les nouvelles ABI cibles auront des valeurs différentes.

TARGET_ABI

Concaténation du niveau d'API Android cible et de l'ABI. Elle est particulièrement utile lorsque vous souhaitez effectuer des tests par rapport à une image système cible spécifique pour un appareil réel. Par exemple, pour rechercher un appareil ARM 64 bits s'exécutant sur l'API Android niveau 22 :

ifeq ($(TARGET_ABI),android-22-arm64-v8a)
  # ... do something ...
endif

Variables de description de module

Les variables de cette section décrivent le module au système de compilation. La description de chaque module doit suivre ce flux de base :

  1. Initialiser ou annuler la définition des variables associées au module à l'aide de la variable CLEAR_VARS
  2. Attribuer des valeurs aux variables utilisées pour décrire le module
  3. Configurer le système de compilation du NDK afin qu'il utilise le script de compilation approprié pour le module, à l'aide de la variable BUILD_XXX

LOCAL_PATH

Cette variable permet d'indiquer le chemin du fichier actuel. Vous devez la définir au début du fichier Android.mk. L'exemple suivant montre comment procéder :

LOCAL_PATH := $(call my-dir)

Le script vers lequel CLEAR_VARS renvoie n'efface pas cette variable. Par conséquent, vous n'avez besoin de le définir qu'une seule fois, même si votre fichier Android.mk décrit plusieurs modules.

LOCAL_MODULE

Cette variable stocke le nom du module. Il doit être unique parmi tous les noms de module et ne contenir aucun espace. Vous devez le définir avant d'inclure des scripts (autres que celui pour CLEAR_VARS). Vous n'avez pas besoin d'ajouter le préfixe lib ni l'extension de fichier .so ou .a. Le système de compilation effectue ces modifications automatiquement. Dans les fichiers Android.mk et Application.mk, faites référence au module par son nom non modifié. Par exemple, la ligne suivante génère un module de bibliothèque partagée appelé libfoo.so :

LOCAL_MODULE := "foo"

Si vous souhaitez que le module généré ait un nom différent de lib + la valeur correspondant à LOCAL_MODULE, vous pouvez utiliser la variable LOCAL_MODULE_FILENAME afin d'attribuer au module généré un nom de votre choix.

LOCAL_MODULE_FILENAME

Cette variable facultative vous permet de remplacer les noms que le système de compilation utilise par défaut pour les fichiers qu'il génère. Par exemple, si le nom de votre LOCAL_MODULE est foo, vous pouvez forcer le système à appeler le fichier qu'il génère libnewfoo. L'exemple suivant montre comment procéder :

LOCAL_MODULE := foo
LOCAL_MODULE_FILENAME := libnewfoo

Pour un module de bibliothèque partagée, cet exemple génère un fichier appelé libnewfoo.so.

LOCAL_SRC_FILES

Cette variable contient la liste des fichiers sources que le système de compilation utilise pour générer le module. Indiquez uniquement les fichiers que le système de compilation transmet au compilateur, car il calculera automatiquement les dépendances associées. Notez que vous pouvez utiliser des chemins d'accès relatifs (à LOCAL_PATH) et des chemins d'accès absolus.

Nous vous recommandons d'éviter les chemins d'accès absolus. Les chemins d'accès relatifs améliorent la portabilité du fichier Android.mk.

LOCAL_CPP_EXTENSION

Vous pouvez utiliser cette variable facultative pour indiquer une extension de fichier autre que .cpp pour vos fichiers sources C++. Par exemple, la ligne suivante remplace l'extension par .cxx (notez que le paramètre doit inclure un point).

LOCAL_CPP_EXTENSION := .cxx

Vous pouvez utiliser cette variable pour spécifier plusieurs extensions. Par exemple :

LOCAL_CPP_EXTENSION := .cxx .cpp .cc

LOCAL_CPP_FEATURES

Vous pouvez utiliser cette variable facultative pour indiquer que votre code repose sur des fonctionnalités C++ spécifiques. Elle active les indicateurs de compilation et d'association appropriées pendant le processus de compilation. Pour les binaires prédéfinis, cette variable déclare également les caractéristiques dont ils dépendent, ce qui permet de garantir que l'association finale fonctionnera correctement. Nous vous recommandons d'utiliser cette variable au lieu d'activer -frtti et -fexceptions directement dans la définition LOCAL_CPPFLAGS.

L'utilisation de cette variable permet au système de compilation de choisir les indicateurs appropriés pour chaque module. Si vous utilisez LOCAL_CPPFLAGS, le compilateur exploite tous les indicateurs spécifiés pour tous les modules, quel que soit le besoin réel.

Par exemple, pour indiquer que votre code utilise des informations de type RTTI, saisissez :

LOCAL_CPP_FEATURES := rtti

Pour indiquer que votre code utilise des exceptions C++, saisissez :

LOCAL_CPP_FEATURES := exceptions

Vous pouvez également spécifier plusieurs valeurs pour cette variable. Par exemple :

LOCAL_CPP_FEATURES := rtti features

L'ordre dans lequel vous décrivez les valeurs n'a pas d'importance.

LOCAL_C_INCLUDES

Vous pouvez utiliser cette variable facultative pour spécifier une liste de chemins d'accès relatifs au répertoire root du NDK, à ajouter au chemin de recherche à inclure lors de la compilation de toutes les sources (C, C++ et Assembly). Par exemple :

LOCAL_C_INCLUDES := sources/foo

Ou encore :

LOCAL_C_INCLUDES := $(LOCAL_PATH)/<subdirectory>/foo

Définissez cette variable avant de définir les indicateurs d'inclusion correspondants via LOCAL_CFLAGS ou LOCAL_CPPFLAGS.

Le système de compilation utilise également les chemins d'accès LOCAL_C_INCLUDES automatiquement lors du lancement du débogage natif avec ndk-gdb.

LOCAL_ASFLAGS

Indicateurs qui seront transmis à Clang lors de la création des fichiers .s ou .S.

LOCAL_ASMFLAGS

Indicateurs qui seront transmis à yasm lors de la création des fichiers .asm.

LOCAL_CFLAGS

Indicateurs transmis à Clang lors de la compilation de fichiers sources C, C++ et certains assemblys (.s et .S, mais pas .asm). Cela peut être utile pour spécifier des définitions de macro ou des options de compilation supplémentaires. Utilisez LOCAL_CPPFLAGS pour spécifier des indicateurs pour C++ uniquement. Utilisez LOCAL_CONLYFLAGS pour spécifier des indicateurs pour C uniquement.

Essayez de ne pas modifier le niveau d'optimisation ou de débogage dans le fichier Android.mk. Le système de compilation gère ce paramètre automatiquement à l'aide des informations pertinentes du fichier Application.mk. Cela permet au système de compilation de générer les fichiers de données qui serviront au débogage.

Pour spécifier des chemins d'inclusion supplémentaires, saisissez :

LOCAL_CFLAGS += -I<path>,

Il est toutefois préférable d'utiliser LOCAL_C_INCLUDES à cette fin, car cette variable permet également d'utiliser les chemins d'accès disponibles pour le débogage natif avec ndk-gdb.

LOCAL_CONLYFLAGS

Options qui seront transmises à Clang lors de la compilation des sources C. Contrairement à LOCAL_CFLAGS, LOCAL_CONLYFLAGS n'est pas transmis à Clang lors de la compilation des sources C++ ou d'assemblage.

LOCAL_CPPFLAGS

Ensemble facultatif d'indicateurs de compilation qui sont transmis lors de la création de fichiers sources C++ uniquement. Elles apparaissent après LOCAL_CFLAGS dans la ligne de commande du compilateur. Utilisez LOCAL_CFLAGS pour spécifier les indicateurs C et C++.

LOCAL_STATIC_LIBRARIES

Cette variable stocke la liste des modules de bibliothèques statiques dont dépend le module actuel.

Si le module actuel est une bibliothèque partagée ou un exécutable, cette variable force ces bibliothèques à être associées au binaire obtenu.

Si le module actuel est une bibliothèque statique, cette variable indique simplement que les autres modules qui en dépendent dépendent également des bibliothèques répertoriées.

LOCAL_SHARED_LIBRARIES

Cette variable correspond à la liste des modules des bibliothèques partagées dont ce module dépend lors de l'exécution. Ces informations sont nécessaires au moment de l'association et pour intégrer les informations correspondantes dans le fichier généré.

LOCAL_WHOLE_STATIC_LIBRARIES

Cette variable est une variante de LOCAL_STATIC_LIBRARIES et exprime l'idée que l'outil d'association doit traiter les modules de bibliothèque associés comme des archives complètes. Pour en savoir plus sur les archives complètes, reportez-vous à l'indicateur --whole-archive dans la documentation GNU ld.

Cette variable est utile lorsqu'il existe des dépendances circulaires entre plusieurs bibliothèques statiques. Lorsque vous utilisez cette variable pour créer une bibliothèque partagée, le système de compilation est contraint d'ajouter tous les fichiers d'objets de vos bibliothèques statiques au fichier binaire final. Toutefois, il n'en est pas de même pour la génération de fichiers exécutables.

LOCAL_LDLIBS

Cette variable contient la liste des indicateurs d'association supplémentaires à utiliser pour créer la bibliothèque partagée ou l'exécutable. Elle vous permet d'utiliser le préfixe -l pour transmettre le nom de bibliothèques système spécifiques. Par exemple, l'exemple suivant indique à l'outil d'association de générer un module qui renvoie vers /system/lib/libz.so au moment du chargement :

LOCAL_LDLIBS := -lz

Pour obtenir la liste des bibliothèques système exposées auxquelles vous pouvez associer cette version de NDK, consultez la page API natives.

LOCAL_LDFLAGS

Liste des autres indicateurs d'association que le système de compilation peut utiliser lors de la création de la bibliothèque partagée ou de l'exécutable. Par exemple, pour utiliser l'outil d'association ld.bfd sur ARM/X86 :

LOCAL_LDFLAGS += -fuse-ld=bfd

LOCAL_ALLOW_UNDEFINED_SYMBOLS

Par défaut, lorsque le système de compilation trouve une référence non définie identifiée lors de la compilation d'un partage, il génère une erreur de type symbole non défini. Cette erreur vous permet de détecter des bugs dans le code source.

Pour désactiver cette vérification, définissez cette variable sur true. Notez que ce paramètre peut entraîner le chargement de la bibliothèque partagée au moment de l'exécution.

LOCAL_ARM_MODE

Par défaut, le système de compilation génère des binaires cibles ARM en mode thumb, où chaque instruction fait 16 bits de large et est liée aux bibliothèques STL du répertoire thumb/. Définir cette variable sur arm force le système de compilation à générer les fichiers d'objets du module en mode arm 32 bits. L'exemple suivant montre comment procéder :

LOCAL_ARM_MODE := arm

Vous pouvez également demander au système de compilation de créer des sources spécifiques uniquement en mode arm en ajoutant le suffixe .arm aux noms des fichiers sources. L'exemple suivant indique au système de compilation de toujours compiler bar.c en mode ARM, mais de compiler foo.c conformément à la valeur de LOCAL_ARM_MODE.

LOCAL_SRC_FILES := foo.c bar.c.arm

LOCAL_ARM_NEON

Cette variable n'a d'importance que lorsque vous ciblez l'ABI armeabi-v7a. Elle permet d'utiliser les fonctionnalités intrinsèques de compilateur d'ARM Advanced SIMD (NEON) dans les sources C et C++, ainsi que les instructions NEON dans les fichiers Assembly.

Notez que les processeurs ARMv7 ne sont pas tous compatibles avec les extensions de l'ensemble d'instructions NEON. C'est pourquoi vous devez effectuer une détection d'exécution afin de pouvoir utiliser ce code en toute sécurité au moment de l'exécution. Pour en savoir plus, consultez les sections Compatibilité avec Neon et Fonctionnalités du processeur.

Vous pouvez également utiliser le suffixe .neon pour indiquer que le système de compilation ne compile que des fichiers sources spécifiques compatibles avec NEON. Dans l'exemple suivant, le système de compilation compile foo.c avec la compatibilité NEON et Thumb, bar.c avec la compatibilité Thumb et zoo.c avec la compatibilité ARM et NEON :

LOCAL_SRC_FILES = foo.c.neon bar.c zoo.c.arm.neon

Si vous utilisez les deux suffixes, .arm doit précéder .neon.

LOCAL_DISABLE_FORMAT_STRING_CHECKS

Par défaut, le système de compilation compile le code avec une protection par chaîne de format. Une erreur de compilation est générée si une chaîne de format non constante est utilisée dans une fonction de style printf. Cette protection est activée par défaut, mais vous pouvez définir la valeur de cette variable sur true pour la désactiver. Nous vous déconseillons toutefois de le faire sans raison valable.

LOCAL_EXPORT_CFLAGS

Cette variable enregistre un ensemble d'indicateurs de compilation C/C++ à ajouter à la définition LOCAL_CFLAGS de tout autre module qui utilise celle-ci via les variables LOCAL_STATIC_LIBRARIES ou LOCAL_SHARED_LIBRARIES.

Prenons l'exemple des deux modules suivants, foo et bar, qui dépendent de foo :

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_CFLAGS := -DFOO=1
include $(BUILD_STATIC_LIBRARY)


include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_CFLAGS := -DBAR=2
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

Ici, le système de compilation transmet les indicateurs -DFOO=1 et -DBAR=2 au compilateur lors de la compilation de bar.c. Il ajoute également des indicateurs exportés au fichier LOCAL_CFLAGS du module afin que vous puissiez les remplacer facilement.

En outre, la relation entre les modules est transitive : si zoo dépend de bar, qui dépend lui-même de foo, alors zoo héritera également de tous les indicateurs exportés à partir de foo.

Enfin, le système de compilation n'utilise pas les indicateurs exportés lors de la compilation locale (c'est-à-dire, lors de la compilation du module dont les indicateurs sont exportés). Ainsi, dans l'exemple ci-dessus, il ne transmet pas -DFOO=1 au compilateur lors de la création de foo/foo.c. Pour compiler en local, utilisez plutôt LOCAL_CFLAGS.

LOCAL_EXPORT_CPPFLAGS

Cette variable est identique à LOCAL_EXPORT_CFLAGS, mais pour les indicateurs C++ uniquement.

LOCAL_EXPORT_C_INCLUDES

Cette variable est identique à LOCAL_EXPORT_CFLAGS, mais pour les chemins d'inclusion C. Elle est utile dans les cas où, par exemple, bar.c doit inclure les en-têtes du module foo.

LOCAL_EXPORT_LDFLAGS

Cette variable est identique à LOCAL_EXPORT_CFLAGS, mais pour les indicateurs d'association.

LOCAL_EXPORT_LDLIBS

Cette variable est identique à LOCAL_EXPORT_CFLAGS et indique au système de compilation de transmettre les noms de bibliothèques système spécifiques au compilateur. Ajoutez le préfixe -l au nom de chaque bibliothèque que vous spécifiez.

Notez que le système de compilation ajoute des indicateurs d'association importés à la valeur de la variable LOCAL_LDLIBS du module. Cela est dû au fonctionnement des outils d'association Unix.

Cette variable est généralement utile lorsque le module foo est une bibliothèque statique dont le code dépend d'une bibliothèque système. Vous pouvez ainsi utiliser LOCAL_EXPORT_LDLIBS pour exporter la dépendance. Par exemple :

include $(CLEAR_VARS)
LOCAL_MODULE := foo
LOCAL_SRC_FILES := foo/foo.c
LOCAL_EXPORT_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)

include $(CLEAR_VARS)
LOCAL_MODULE := bar
LOCAL_SRC_FILES := bar.c
LOCAL_STATIC_LIBRARIES := foo
include $(BUILD_SHARED_LIBRARY)

Dans cet exemple, le système de compilation place -llog à la fin de la commande d'association lorsqu'il compile libbar.so. Cela indique à l'outil d'association que, comme libbar.so dépend de foo, il dépend également de la bibliothèque de journalisation système.

LOCAL_SHORT_COMMANDS

Définissez cette variable sur true lorsque votre module comporte un très grand nombre de sources et/ou de bibliothèques statiques ou partagées dépendantes. Cela oblige le système de compilation à utiliser la syntaxe @ pour les archives contenant des fichiers d'objets intermédiaires ou des bibliothèques d'association.

Cette fonctionnalité peut être utile sur Windows, où la ligne de commande n'accepte pas plus de 8 191 caractères, ce qui ne suffit pas toujours pour les projets complexes. Cela a également un impact sur la compilation des fichiers sources individuels, qui placent presque tous les indicateurs de compilation dans des fichiers de liste.

Notez que toute valeur autre que true rétablira le comportement par défaut. Vous pouvez également définir APP_SHORT_COMMANDS dans votre fichier Application.mk pour forcer ce comportement pour tous les modules de votre projet.

Nous vous déconseillons d'activer cette fonctionnalité par défaut, car elle ralentit la compilation.

LOCAL_THIN_ARCHIVE

Définissez cette variable sur true lorsque vous créez des bibliothèques statiques. Cela entraînera la création d'une archive fine, c'est-à-dire un fichier de bibliothèque ne contenant pas de fichiers d'objets, mais seulement des chemins d'accès aux objets qu'il contiendrait normalement.

Cette approche est utile pour réduire la taille de la sortie de compilation. L'inconvénient est que ces bibliothèques ne peuvent pas être déplacées vers un autre emplacement (tous les chemins qu'elles contiennent sont relatifs).

Les valeurs valides sont true, false ou vides. Vous pouvez définir une valeur par défaut dans le fichier Application.mk via la variable APP_THIN_ARCHIVE.

LOCAL_FILTER_ASM

Définissez cette variable en tant que commande d'interface système que le système de compilation utilisera pour filtrer les fichiers d'assemblage extraits ou générés à partir des fichiers spécifiés pour LOCAL_SRC_FILES. La définition de cette variable a les conséquences suivantes :

  1. Le système de compilation génère un fichier d'assemblage temporaire à partir de n'importe quel fichier source C ou C++, au lieu de le compiler dans un fichier objet.
  2. Le système de compilation exécute la commande d'interface système dans LOCAL_FILTER_ASM au niveau de tous les fichiers d'assemblage temporaires et de tous les fichiers d'assemblage indiqués dans LOCAL_SRC_FILES, ce qui génère un autre fichier d'assemblage temporaire.
  3. Le système de compilation compile ces fichiers d'assemblage filtrés dans un fichier objet.

Par exemple :

LOCAL_SRC_FILES  := foo.c bar.S
LOCAL_FILTER_ASM :=

foo.c --1--> $OBJS_DIR/foo.S.original --2--> $OBJS_DIR/foo.S --3--> $OBJS_DIR/foo.o
bar.S                                 --2--> $OBJS_DIR/bar.S --3--> $OBJS_DIR/bar.o

"1" correspond au compilateur, "2" au filtre et "3" à l'assembleur. Le filtre doit être une commande d'interface système autonome qui utilise le nom du fichier d'entrée comme premier argument et le nom du fichier de sortie comme deuxième argument. Par exemple :

myasmfilter $OBJS_DIR/foo.S.original $OBJS_DIR/foo.S
myasmfilter bar.S $OBJS_DIR/bar.S

Macros de fonction fournies par le NDK

Cette section décrit les macros de fonction GNU Maker fournies par le NDK. Utilisez $(call <function>) pour les évaluer. Elles renvoient des informations textuelles.

my-dir

Cette macro renvoie le chemin du dernier fichier makefile inclus, qui correspond généralement au répertoire Android.mk actuel. my-dir sert à définir LOCAL_PATH au début du fichier Android.mk. Par exemple :

LOCAL_PATH := $(call my-dir)

En raison du fonctionnement de GNU Make, cette macro renvoie le chemin du dernier fichier makefile que le système de compilation a inclus lors de l'analyse des scripts de compilation. C'est pourquoi vous ne devez pas appeler my-dir après avoir inclus un autre fichier.

Prenons l'exemple suivant :

LOCAL_PATH := $(call my-dir)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(call my-dir)

# ... declare another module

Le problème ici est que le deuxième appel à my-dir définit LOCAL_PATH comme $PATH/foo au lieu de $PATH, car c'est vers cet emplacement que sa dernière inclusion renvoyait.

Pour éviter ce problème, ajoutez des inclusions supplémentaires après tout le reste dans le fichier Android.mk. Par exemple :

LOCAL_PATH := $(call my-dir)

# ... declare one module

LOCAL_PATH := $(call my-dir)

# ... declare another module

# extra includes at the end of the Android.mk file
include $(LOCAL_PATH)/foo/Android.mk

S'il n'est pas possible de structurer le fichier de cette manière, enregistrez la valeur du premier appel my-dir dans une autre variable. Par exemple :

MY_LOCAL_PATH := $(call my-dir)

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare one module

include $(LOCAL_PATH)/foo/`Android.mk`

LOCAL_PATH := $(MY_LOCAL_PATH)

# ... declare another module

all-subdir-makefiles

Renvoie la liste des fichiers Android.mk situés dans tous les sous-répertoires du chemin my-dir actuel.

Vous pouvez utiliser cette fonction pour indiquer les hiérarchies de répertoires sources imbriquées au système de compilation. Par défaut, le NDK recherche uniquement les fichiers du répertoire contenant le fichier Android.mk.

this-makefile

Renvoie le chemin du fichier makefile actuel (à partir duquel le système de compilation a appelé la fonction).

parent-makefile

Renvoie le chemin d'accès au fichier makefile parent dans l'arborescence d'inclusion (chemin d'accès du fichier makefile qui contient le fichier actuel).

grand-parent-makefile

Renvoie le chemin du fichier makefile grand-parent de l'arborescence d'inclusion (chemin d'accès du fichier makefile qui contient le fichier actuel).

import-module

Fonction qui vous permet de rechercher et d'inclure le fichier Android.mk d'un module par son nom. Voici un exemple type :

$(call import-module,<name>)

Dans cet exemple, le système de compilation recherche le module balisé <name> dans la liste des répertoires référencés par la variable d'environnement NDK_MODULE_PATH, et inclut automatiquement son fichier Android.mk.