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 funcionalidad:

  • La distribución de tus propias bibliotecas a desarrolladores del NDK externos 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.

Declaración de una biblioteca compilada previamente

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

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

    Nota: Debes asegurarte de seleccionar la versión de tu biblioteca compilada previamente que sea adecuada para tu ABI de destino. Si deseas obtener más información sobre cómo garantizar la compatibilidad de las bibliotecas para las ABI, consulta Selección de ABI para bibliotecas compiladas previamente.

  3. Incluye PREBUILT_SHARED_LIBRARY o PREBUILT_STATIC_LIBRARY, según si usas una biblioteca compartida (.so) o estática (.a).

Aquí te mostramos un ejemplo simple en el cual se prevé que la biblioteca compilada previamente libfoo.so 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 compilada previamente.

El sistema de compilación dispone una copia de tu biblioteca compartida compilada previamente en $PROJECT/obj/local, y otra copia, 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 compilada previamente desde otros módulos

Para hacer referencia a una biblioteca compilada previamente 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 con 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)
    

Aquí, 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í.

Exportación de encabezados para bibliotecas compiladas previamente

El código en foo-user.c depende de declaraciones específicas que normalmente se encuentran en un archivo de encabezado, como foo.h, distribuido con la biblioteca compilada previamente. 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 de inclusión 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 compilado previamente. Por ejemplo, siempre que el encabezado foo.h se encuentre en el directorio include asociado con el módulo compilado previamente, puedes 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 exportará la ruta de acceso al directorio include de la biblioteca compilada previamente y anexará esa ruta de acceso al valor de LOCAL_C_INCLUDES para el módulo que depende de él.

Esta operación permite que el sistema de compilación busque los encabezados necesarios.

Depuración de bibliotecas compiladas previamente

Te recomendamos proporcionar bibliotecas compartidas compiladas previamente que contengan símbolos de depuración. El sistema de compilación del NDK siempre extrae 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 correcta de tu biblioteca compartida compilada previamente para tu ABI de destino. La variable TARGET_ARCH_ABI en el archivo Android.mk puede dirigir el sistema de compilación hacia la versión adecuada de la biblioteca.

Por ejemplo, supón 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 valor de TARGET_ARCH_ABI, el sistema de compilación usa la versión de libfoo.so que se encuentra en el directorio armeabi. Si especificaste x86 como el valor de TARGET_ARCH_ABI, el sistema de compilación usa la versión que se indica en el directorio x86.