NDK 支持使用預編譯庫(同時支持靜態庫和共享庫)。此功能有如下兩個主要用例:html
- 向第三方 NDK 開發者分發您本身的庫(而不分發您的源代碼)。
- 使用您本身的庫的預編譯版原本提高編譯速度。
本頁將介紹如何使用預編譯庫。android
聲明預編譯庫
您必須將本身使用的每一個預編譯庫聲明爲一個獨立模塊。爲此,請執行如下步驟:ide
- 爲模塊提供名稱。此名稱不須要與預編譯庫自己的名稱相同。
- 在模塊的
Android.mk
文件中,將指向您提供的預編譯庫的路徑分配到LOCAL_SRC_FILES
。指定LOCAL_PATH
變量的值的相對路徑。注意:請務必選擇與您的目標 ABI 對應的預編譯庫版本。要詳細瞭解如何確保庫支持 ABI,請參閱爲預編譯庫選擇 ABI。ui
- 根據您使用的是共享庫 (
.so
) 仍是靜態庫 (.a
),添加PREBUILT_SHARED_LIBRARY
或PREBUILT_STATIC_LIBRARY
。
下面這個小例子假設預編譯庫 libfoo.so
與描述它的 Android.mk
文件位於同一個目錄中。this
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := foo-prebuilt LOCAL_SRC_FILES := libfoo.so include $(PREBUILT_SHARED_LIBRARY)
在此示例中,模塊名稱與預編譯庫的名稱相同。spa
編譯系統會將您的預編譯共享庫副本置於 $PROJECT/obj/local
中,而將另外一個提取的調試信息的副本置於 $PROJECT/libs/<abi>
中。在這裏,$PROJECT
是您項目的根目錄。調試
從其餘模塊引用預編譯庫
要從其餘模塊引用預編譯庫,請在與這些模塊關聯的 Android.mk
文件中,將該預編譯庫的名稱指定爲 LOCAL_STATIC_LIBRARIES
或 LOCAL_SHARED_LIBRARIES
變量。code
例如,使用 libfoo.so
的模塊說明可能相似於如下內容:htm
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
目錄中的版本。