Utiliser des bibliothèques prédéfinies

Le NDK accepte l'utilisation de bibliothèques prédéfinies statiques ou partagées. Cette fonctionnalité répond principalement aux deux cas d'utilisation suivants :

  • Distribuer vos propres bibliothèques à des développeurs de NDK tiers sans avoir à distribuer vos sources
  • Utiliser une version prédéfinie de vos propres bibliothèques pour accélérer la compilation

Cette page explique comment utiliser les bibliothèques prédéfinies.

Déclarer une bibliothèque prédéfinie

Vous devez déclarer chaque bibliothèque prédéfinie que vous utilisez en tant que module indépendant. Pour ce faire, procédez comme suit :

  1. Attribuez un nom au module. Ce nom n'a pas besoin d'être identique à celui de la bibliothèque prédéfinie.
  2. Dans le fichier Android.mk du module, attribuez à LOCAL_SRC_FILES le chemin d'accès à la bibliothèque prédéfinie que vous fournissez. Spécifiez le chemin d'accès par rapport à la valeur de votre variable LOCAL_PATH.

  3. Incluez PREBUILT_SHARED_LIBRARY ou PREBUILT_STATIC_LIBRARY, selon que vous utilisez une bibliothèque partagée (.so) ou statique (.a).

Voici un exemple simple qui suppose que la bibliothèque prédéfinie libfoo.so se trouve dans le même répertoire que le fichier Android.mk qui la décrit.

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)

Dans cet exemple, le nom du module est identique à celui de la bibliothèque prédéfinie.

Le système de compilation place une copie de la bibliothèque partagée prédéfinie dans $PROJECT/obj/local et une autre copie, sans les informations de débogage, dans $PROJECT/libs/<abi>. Ici, $PROJECT est le répertoire racine du projet.

Référencer la bibliothèque prédéfinie d'autres modules

Pour référencer une bibliothèque prédéfinie à partir d'autres modules, spécifiez son nom en tant que valeur de la variable LOCAL_STATIC_LIBRARIES ou LOCAL_SHARED_LIBRARIES dans les fichiers Android.mk associés à ces autres modules.

Par exemple, la description d'un module avec libfoo.so peut se présenter comme suit :

include $(CLEAR_VARS)
LOCAL_MODULE := foo-user
LOCAL_SRC_FILES := foo-user.c
LOCAL_SHARED_LIBRARIES := foo-prebuilt
include $(BUILD_SHARED_LIBRARY)

Ici, LOCAL_MODULE est le nom du module faisant référence à la bibliothèque prédéfinie. LOCAL_SHARED_LIBRARIES est le nom de la bibliothèque prédéfinie elle-même.

Exporter les en-têtes pour les bibliothèques prédéfinies

Le code dans foo-user.c dépend de déclarations spécifiques qui se trouvent généralement dans un fichier d'en-tête, tel que foo.h, distribué avec la bibliothèque prédéfinie. Par exemple, foo-user.c peut contenir une ligne semblable à celle-ci :

#include <foo.h>

Dans ce cas, vous devez fournir l'en-tête et son chemin d'inclusion au compilateur lorsque vous créez le module foo-user. Pour effectuer cette tâche, une méthode simple consiste à utiliser des exportations dans la définition du module prédéfini. Par exemple, tant que l'en-tête foo.h se trouve dans le répertoire include associé au module prédéfini, vous pouvez le déclarer comme suit :

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

La définition LOCAL_EXPORT_C_INCLUDES garantit ici que le système de compilation exporte le chemin d'accès au répertoire include de la bibliothèque prédéfinie, en ajoutant ce chemin à la valeur de LOCAL_C_INCLUDES pour le module qui en dépend.

Cette opération permet au système de compilation d'identifier les en-têtes nécessaires.

Déboguer les bibliothèques prédéfinies

Nous vous recommandons de fournir des bibliothèques partagées prédéfinies contenant des symboles de débogage. Le système de compilation du NDK supprime toujours les symboles de la version de la bibliothèque qu'il installe dans $PROJECT/libs/<abi>/, mais vous pouvez utiliser la version de débogage pour le débogage avec ndk-gdb.

Sélectionner des ABI pour les bibliothèques prédéfinies

Veillez à sélectionner la version de bibliothèque partagée prédéfinie adaptée à votre ABI cible. La variable TARGET_ARCH_ABI du fichier Android.mk peut renvoyer le système de compilation à la version appropriée de la bibliothèque.

Par exemple, supposons que votre projet contienne deux versions de la bibliothèque libfoo.so :

armeabi/libfoo.so
x86/libfoo.so

L'extrait de code suivant montre comment utiliser TARGET_ARCH_ABI pour que le système de compilation sélectionne la version appropriée de la bibliothèque :

include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)

Si vous avez spécifié armeabi comme valeur de TARGET_ARCH_ABI, le système de compilation utilise la version de libfoo.so située dans le répertoire armeabi. Si vous avez spécifié x86 comme valeur TARGET_ARCH_ABI, le système de compilation utilise la version qui se trouve dans le répertoire x86.