Usar bibliotecas pré-criadas

O NDK permite o uso de bibliotecas pré-compiladas, tanto estáticas quanto compartilhadas. Há dois casos de uso principais dessa funcionalidade:

  • Distribuir bibliotecas próprias a desenvolvedores de terceiros que usam NDK sem distribuir suas fontes.
  • Usar uma versão pré-criada das próprias bibliotecas para acelerar o build.

Esta página explica como usar bibliotecas pré-compiladas.

Declarar uma biblioteca pré-compilada

Declare cada biblioteca pré-compilada que você usa como um módulo independente. Para fazer isso, siga estas etapas:

  1. Dê um nome ao módulo. Esse nome não precisa ser igual ao da biblioteca pré-compilada.
  2. No arquivo Android.mk do módulo, atribua a LOCAL_SRC_FILES o caminho para a biblioteca pré-compilada fornecida. Especifique o caminho em relação ao valor da sua variável LOCAL_PATH.

  3. Inclua PREBUILT_SHARED_LIBRARY ou PREBUILT_STATIC_LIBRARY, de acordo com a biblioteca que você está usando: compartilhada (.so) ou estática (.a).

Este é um exemplo trivial que presume que a biblioteca pré-compilada libfoo.so reside no mesmo diretório do arquivo Android.mk que a descreve.

LOCAL_PATH := $(call my-dir)

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

Nesse exemplo, o nome do módulo é igual ao da biblioteca pré-compilada.

O sistema de compilação coloca uma cópia da biblioteca compartilhada pré-compilada em $PROJECT/obj/local e outra cópia, sem informações de depuração, em $PROJECT/libs/<abi>. Aqui, $PROJECT é o diretório raiz do seu projeto.

Referenciar a biblioteca pré-compilada de outros módulos

Para referenciar a biblioteca pré-compilada de outros módulos, especifique o nome dela como o valor da variável LOCAL_STATIC_LIBRARIES ou LOCAL_SHARED_LIBRARIES nos arquivos Android.mk associados a esses outros módulos.

Por exemplo, a descrição de um módulo que usa libfoo.so pode ser a seguinte:

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

Aqui, LOCAL_MODULE é o nome do módulo que referencia a biblioteca pré-compilada, e LOCAL_SHARED_LIBRARIES é o nome da biblioteca.

Exportar cabeçalhos para bibliotecas pré-compiladas

O código em foo-user.c depende de declarações específicas normalmente localizadas em um arquivo principal, como foo.h, fornecido com a biblioteca pré-compilada. Por exemplo, foo-user.c pode ter uma linha como a seguinte:

#include <foo.h>

Nesse caso, você precisa fornecer o cabeçalho e o caminho de inclusão dele para o compilador ao criar o módulo foo-user. Uma forma simples de fazer isso é usar exportações na definição do módulo pré-compilado. Por exemplo, se o cabeçalho foo.h estiver localizado no diretório include associado ao módulo pré-compilado, você poderá declará-lo da seguinte maneira:

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

A definição de LOCAL_EXPORT_C_INCLUDES aqui presente garante que o sistema de compilação exporte o caminho para o diretório include da biblioteca pré-compilada, adicionando esse caminho ao valor de LOCAL_C_INCLUDES do módulo que depende dele.

Essa operação permite que o sistema de compilação encontre os cabeçalhos necessários.

Depurar bibliotecas pré-compiladas

Recomendamos que você forneça bibliotecas compartilhadas pré-compiladas que contenham símbolos de depuração. O sistema de compilação do NDK sempre remove os símbolos da versão da biblioteca que é instalada em $PROJECT/libs/<abi>/, mas você pode usar a versão de depuração para depuração com ndk-gdb.

Selecionar ABIs para bibliotecas pré-compiladas

Você precisa selecionar a versão correta da biblioteca compartilhada pré-compilada para sua ABI de destino. A variável TARGET_ARCH_ABI no arquivo Android.mk pode direcionar o sistema de compilação à versão adequada da biblioteca.

Por exemplo, suponha que o projeto contenha duas versões da biblioteca libfoo.so:

armeabi/libfoo.so
x86/libfoo.so

O snippet a seguir mostra como usar TARGET_ARCH_ABI para que o sistema de compilação selecione a versão apropriada da 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)

Se você especificou armeabi como o valor de TARGET_ARCH_ABI, o sistema de compilação usa a versão de libfoo.so localizada no diretório armeabi. Se você especificou x86 como o valor TARGET_ARCH_ABI, o sistema de compilação usa a versão no diretório x86.