Uso de bibliotecas compiladas previamente

El NDK admite el uso de bibliotecas compiladas previamente, tanto estáticas como compartidas. Existen dos casos prácticos principales para esta función:

  • La distribución de tus propias bibliotecas a desarrolladores del NDK de terceros sin distribuir tus fuentes.
  • El uso de una versión de tus propias bibliotecas compilada previamente para acelerar la compilación.

En esta página se explica la manera de usar bibliotecas compiladas previamente.

Cómo declarar una biblioteca previamente compilada

Debes declarar cada biblioteca previamente compilada que uses como módulo independiente. Para hacerlo, sigue estos pasos:

  1. Dale un nombre al módulo. No es necesario que sea el mismo que el de la biblioteca previamente compilada.
  2. En el archivo Android.mk del módulo, asigna a LOCAL_SRC_FILES la ruta de acceso a la biblioteca previamente compilada que vas a proporcionar. Especifica la ruta de acceso relacionada con el valor de la variable LOCAL_PATH.

  3. Incluye PREBUILT_SHARED_LIBRARY o PREBUILT_STATIC_LIBRARY, dependiendo de 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 se encuentra 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 previamente compilada.

El sistema de compilación guarda una copia de la biblioteca previamente compilada que compartiste 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 previamente 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 esos 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 normalmente se encuentran 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 su ruta de acceso al compilador cuando compiles el módulo foo-user. Una forma sencilla de realizar esta tarea es usar exportaciones en la definición del módulo previamente compilado. Por ejemplo, siempre que el encabezado foo.h se encuentre 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 previamente compilada, 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

Te recomendamos que proporciones bibliotecas previamente compiladas que hayas compartido y que contengan 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 realizar depuraciones con ndk-gdb.

Selección de ABI para bibliotecas compiladas previamente

Debes asegurarte de seleccionar la versión de la biblioteca previamente compilada que hayas compartido que sea correcta para tu ABI de destino. La variable TARGET_ARCH_ABI del archivo Android.mk puede hacer que el sistema de compilación apunte a la versión adecuada de la biblioteca.

Por ejemplo, supongamos que tu proyecto contiene dos versiones de la biblioteca libfoo.so:

armeabi/libfoo.so
    x86/libfoo.so
    

En el siguiente fragmento, se muestra la forma de 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 usa 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 utiliza la versión del directorio x86.