El NDK admite el uso de bibliotecas previamente compiladas, tanto estáticas como compartidas. Hay dos casos prácticos principales para esta función:
- La distribución de las bibliotecas propias a desarrolladores del NDK de terceros sin distribuir tus fuentes.
- El uso de una versión compilada previamente de las bibliotecas propias para acelerar la compilación.
En esta página, se explica la manera de usar bibliotecas previamente compiladas.
Cómo declarar una biblioteca previamente compilada
Debes declarar cada biblioteca previamente compilada que uses como módulo independiente. Para hacerlo, sigue estos pasos:
- Dale un nombre al módulo. No es necesario que sea el mismo que el de la biblioteca previamente compilada.
En el archivo Android.mk del módulo, asigna a
LOCAL_SRC_FILES
la ruta de acceso a la biblioteca previamente compilada que proporcionarás. Especifica la ruta de acceso relacionada con el valor de la variableLOCAL_PATH
.Incluye
PREBUILT_SHARED_LIBRARY
oPREBUILT_STATIC_LIBRARY
, según si usas una biblioteca compartida (.so
) o estática (.a
).
Aquí te mostramos un ejemplo simple en el que se supone que la biblioteca libfoo.so
previamente compilada está en el mismo directorio que el archivo Android.mk que la describe.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)
En este ejemplo, el nombre del módulo es el mismo que el de la biblioteca compilada previamente.
El sistema de compilación guarda una copia de la biblioteca compilada previamente compartida en $PROJECT/obj/local
y otra sin información de depuración en $PROJECT/libs/<abi>
. Aquí, $PROJECT
es el directorio raíz de tu proyecto.
Cómo hacer referencia a la biblioteca previamente compilada desde otros módulos
Para hacer referencia a una biblioteca previamente compilada desde otros módulos, especifica su nombre como el valor de la variable LOCAL_STATIC_LIBRARIES
o LOCAL_SHARED_LIBRARIES
en los archivos Android.mk asociados con los otros módulos.
Por ejemplo, la descripción de un módulo que usa libfoo.so
podría ser la siguiente:
include $(CLEAR_VARS)
LOCAL_MODULE := foo-user
LOCAL_SRC_FILES := foo-user.c
LOCAL_SHARED_LIBRARIES := foo-prebuilt
include $(BUILD_SHARED_LIBRARY)
En este ejemplo, LOCAL_MODULE
es el nombre del módulo que hace referencia a la compilación previa; LOCAL_SHARED_LIBRARIES
es el nombre de la compilación previa en sí.
Cómo exportar encabezados para bibliotecas previamente compiladas
El código de foo-user.c
depende de declaraciones específicas que, en general, están en un archivo de encabezado, como foo.h
, distribuido con la biblioteca previamente compilada. Por ejemplo, foo-user.c
podría tener una línea como la siguiente:
#include <foo.h>
En ese caso, debes proporcionar el encabezado y la ruta de acceso al compilador cuando compiles el módulo foo-user
. Una forma sencilla de hacer eso es usar exportaciones en la definición del módulo compilado previamente. Por ejemplo, siempre que el encabezado foo.h
esté en el directorio include
asociado con el módulo compilado previamente, podrás declararlo de la siguiente manera:
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
La definición LOCAL_EXPORT_C_INCLUDES
garantiza que el sistema de compilación exporte la ruta de acceso al directorio include
de la biblioteca compilada previamente y que la anexe al valor de LOCAL_C_INCLUDES
para el módulo que depende de ella.
Esta operación permite que el sistema de compilación busque los encabezados necesarios.
Cómo depurar bibliotecas previamente compiladas
Recomendamos que proporciones bibliotecas previamente compiladas compartidas y con símbolos de depuración. El sistema de compilación del NDK siempre quita los símbolos de la versión de la biblioteca que instala en $PROJECT/libs/<abi>/
, pero puedes usar la versión de depuración para hacer depuraciones con ndk-gdb
.
Cómo seleccionar ABI para bibliotecas previamente compiladas
Debes asegurarte de seleccionar la versión de la biblioteca previamente compilada que hayas compartido y que sea correcta para la ABI de destino. La variable TARGET_ARCH_ABI
del archivo Android.mk puede apuntar el sistema de compilación a la versión adecuada de la biblioteca.
Por ejemplo, supongamos que tu proyecto tiene dos versiones de la biblioteca libfoo.so
:
armeabi/libfoo.so
x86/libfoo.so
En el siguiente fragmento, se muestra cómo usar TARGET_ARCH_ABI
de modo que el sistema de compilación seleccione la versión adecuada de la biblioteca:
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 especificaste armeabi
como el valor de TARGET_ARCH_ABI
, el sistema de compilación usará la versión de libfoo.so
ubicada en el directorio armeabi
. Si especificaste x86
como el valor TARGET_ARCH_ABI
, el sistema de compilación usará la versión del directorio x86
.