NDK 支持使用预构建库,包括静态库和共享库。此功能有两个主要用例:
- 将您自己的库分发给第三方 NDK 开发人员,而无需分发您的源代码。
- 使用您自己的库的预构建版本来加快构建速度。
本页介绍如何使用预构建库。
声明预构建库
您必须将使用的每个预构建库声明为一个独立的模块。为此,请执行以下步骤:
- 为模块命名。此名称不必与预构建库本身的名称相同。
在模块的 Android.mk 文件中,将
LOCAL_SRC_FILES
赋值为提供预构建库的路径。指定相对于LOCAL_PATH
变量值的路径。根据使用共享库(
.so
)还是静态库(.a
),包含PREBUILT_SHARED_LIBRARY
或PREBUILT_STATIC_LIBRARY
。
以下是一个简单的示例,假设预构建库 libfoo.so
位于与描述它的 Android.mk 文件相同的目录中。
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
include $(PREBUILT_SHARED_LIBRARY)
在此示例中,模块的名称与预构建库的名称相同。
构建系统会将预构建共享库的副本放置到 $PROJECT/obj/local
中,并将另一个副本(剥离调试信息)放置到 $PROJECT/libs/<abi>
中。在此,$PROJECT
是项目的根目录。
从其他模块引用预构建库
要从其他模块引用预构建库,请在与这些其他模块关联的 Android.mk 文件中,将预构建库的名称指定为 LOCAL_STATIC_LIBRARIES
或 LOCAL_SHARED_LIBRARIES
变量的值。
例如,使用 libfoo.so
的模块的描述可能如下所示:
include $(CLEAR_VARS)
LOCAL_MODULE := foo-user
LOCAL_SRC_FILES := foo-user.c
LOCAL_SHARED_LIBRARIES := foo-prebuilt
include $(BUILD_SHARED_LIBRARY)
在此,LOCAL_MODULE
是引用预构建库的模块的名称;LOCAL_SHARED_LIBRARIES
是预构建库本身的名称。
导出预构建库的标头
foo-user.c
中的代码依赖于通常驻留在标头文件中的特定声明,例如与预构建库一起分发的 foo.h
。例如,foo-user.c
可能包含以下行:
#include <foo.h>
在这种情况下,您需要在构建 foo-user
模块时向编译器提供标头及其包含路径。完成此任务的一个简单方法是使用预构建模块定义中的导出。例如,只要标头 foo.h
位于与预构建模块关联的 include
目录下,您就可以将其声明如下:
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
此处的 LOCAL_EXPORT_C_INCLUDES
定义确保构建系统导出预构建库的 include
目录的路径,并将该路径附加到依赖它的模块的 LOCAL_C_INCLUDES
值的前面。
此操作允许构建系统找到必要的头文件。
调试预构建库
我们建议您提供包含调试符号的预构建共享库。NDK 构建系统始终会从安装到 $PROJECT/libs/<abi>/
中的库版本中剥离符号,但您可以使用调试版本与 ndk-gdb
进行调试。
选择预构建库的 ABI
您必须确保为目标 ABI 选择预构建共享库的正确版本。 TARGET_ARCH_ABI
变量在 Android.mk 文件中可以将构建系统指向库的适当版本。
例如,假设您的项目包含两个版本的库 libfoo.so
armeabi/libfoo.so
x86/libfoo.so
以下代码段显示了如何使用 TARGET_ARCH_ABI
使构建系统选择库的适当版本
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)
如果您已将 armeabi
指定为 TARGET_ARCH_ABI
的值,则构建系统将使用位于 armeabi
目录中的 libfoo.so
版本。如果您已将 x86
指定为 TARGET_ARCH_ABI
的值,则构建系统将使用位于 x86
目录中的版本。