使用预构建库

NDK 支持使用预构建库,包括静态库和共享库。此功能主要有两个用例

  • 在不分发源代码的情况下,将您自己的库分发给第三方 NDK 开发人员。
  • 使用您自己库的预构建版本来加快构建速度。

此页面说明如何使用预构建库。

声明预构建库

您必须将使用的每个预构建库声明为一个独立的模块。为此,请执行以下步骤

  1. 为模块命名。此名称不必与预构建库本身的名称相同。
  2. 在模块的 Android.mk 文件中,将 LOCAL_SRC_FILES 赋值为提供的预构建库的路径。指定相对于 LOCAL_PATH 变量值的路径。

  3. 根据使用的是共享库(.so)还是静态库(.a),包含 PREBUILT_SHARED_LIBRARYPREBUILT_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_LIBRARIESLOCAL_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 目录中的版本。