使用預編譯庫
NDK 支持使用預編譯庫(同時支持靜態庫和共享庫)。此功能有以下兩個主要用例:
- 向第三方 NDK 開發者分發您自己的庫(而不分發您的源代碼)。
- 使用您自己的庫的預編譯版本來提升編譯速度。
本頁將介紹如何使用預編譯庫。
聲明預編譯庫
您必須將自己使用的每個預編譯庫聲明為一個獨立模塊。為此,請執行以下步驟:
- 為模塊提供名稱。此名稱不需要與預編譯庫本身的名稱相同。
- 在模塊的
Android.mk文件中,將指向您提供的預編譯庫的路徑分配到LOCAL_SRC_FILES。指定LOCAL_PATH變量的值的相對路徑。注意:請務必選擇與您的目標 ABI 對應的預編譯庫版本。要詳細了解如何確保庫支持 ABI,請參閱為預編譯庫選擇 ABI。
- 根據您使用的是共享庫 (
.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 模塊,則需要提供標頭及其指向編譯器的 include 路徑。完成此任務的一個簡單方法是在預編譯模塊定義中使用導出內容。例如,只要標頭 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 選擇正確版本的預編譯共享庫。Android.mk 文件中的 TARGET_ARCH_ABI 變量可以將編譯系統指向適當版本的庫。
例如,假設您的項目包含庫 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 目錄中的版本。
