2dx NDK提供的共享庫(Prebuilt)

原文地址:http://blog.csdn.net/smfwuxiao/article/details/8523479 工具

Android NDK r5 開始支持預編譯庫(動態庫和靜態庫),即程序能使用庫的預編譯版本。 ui

該特性可用於如下兩方面: spa

1)向第三方NDK開發人員發佈你的共享庫而不用提供源碼。
2)使用一個提早編譯好的庫(預編譯庫)來加速編譯過程。

本文說明該特性如何工做。 .net

I. 聲明一個預編譯庫的模塊

對於Android編譯工具而言,每一個預編譯庫必須聲明爲一個獨立的模塊。這裏舉一個例子,假設 libfoo.so 文件與 Android.mk 位於同一個目錄:
[plain]  view plain copy
  1. LOCAL_PATH := $(call my-dir)  
  2. include $(CLEAR_VARS)  
  3. LOCAL_MODULE := foo-prebuilt  
  4. LOCAL_SRC_FILES := libfoo.so  
  5. include $(PREBUILT_SHARED_LIBRARY)  
按如下步驟聲明這樣一個模塊:
1. 給該模塊取一個名字(這裏是 foo-prebuilt)。這個名字不須要與預編譯庫自身的名字相同。
2. 將 LOCAL_SRC_FILES 指定爲你要提供的共享庫的路徑。一般,該路徑是相對於 LOCAL_PATH 的路徑。注意:必須保證共享庫ABI的兼容性。
3. 若是你的庫是共享庫,則包含 PREBUILT_SHARED_LIBRARY 而不是 BUILD_SHARED_LIBRARY;若是是靜態庫,則包含 PREBUILT_STATIC_LIBRARY。

預編譯模塊不須要編譯。該預編譯模塊會被拷貝到 $PROJECT/obj/local 下面,還會被拷貝到 $PROJECT/libs/<abi> 下面(這裏的庫被strip過)。 調試

II. 在其餘模塊中引用這個預編譯庫

在依賴該預編譯庫的模塊對應的Android.mk中,將預編譯庫的名字(前面取的)加入到 LOCAL_STATIC_LIBRARIES 或 LOCAL_SHARED_LIBRARIES 聲明中。例如,一個使用上面libfoo.so的簡單例子以下: blog

[plain]  view plain copy
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo-user  
  3. LOCAL_SRC_FILES := foo-user.c  
  4. LOCAL_SHARED_LIBRARIES := foo-prebuilt  
  5. include $(BUILD_SHARED_LIBRARY)  

III. 將預編譯庫的頭文件導出

獲得預編譯庫以後,通常須要它對應的頭文件。例如前面的libfoo.so,它有對應的foo.h。編譯依賴libfoo.so的模塊時,須要將該頭文件和它的路徑提供給NDK編譯系統。一種簡單方法是,前面在定義該預編譯庫的時候,使用LOCAL_EXPORT_C_INCLUDES 變量。例如,假設文件 foo.h 位於當前預編譯模塊所在目錄的 include 子目錄,則能夠在預編譯模塊的Android.mk文件中編寫以下: ip

[plain]  view plain copy
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo-prebuilt  
  3. LOCAL_SRC_FILES := libfoo.so  
  4. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include  
  5. include $(PREBUILT_SHARED_LIBRARY)  
這個 LOCAL_EXPORT_C_INCLUDES 定義確保了任何依賴這個預編譯庫的模塊會自動在本身的 LOCAL_C_INCLUDES 變量中增長到這個預編譯庫的include目錄的路徑,從而可以找到其中的頭文件。

IV. 調試預編譯庫

建議你在預編譯庫中保留調試信息。位於 $PROJECT/libs/<abi> 的版本都是不含調試信息的(被NDK編譯系統執行strip過的),調試版的庫才能用於 ndk-gdb。 開發

V. 共享庫ABI的選擇

如前所述,共享庫與目標系統的ABI兼容性相當重要。應檢查一下 TARGET_ARCH_ABI 的值,能夠是如下值:
armeabi        目標系統CPU是ARMv5TE或更高
armeabi-v7a    目標系統CPU是ARMv7或更高
x86            目標系統CPU是x86
注意,armeabi-v7a的CPU能夠很好地執行armeabi的程序。
舉一個例子,咱們提供一個預編譯庫的兩個版本,而後選擇不一樣的ABI: get

[plain]  view plain copy
  1. include $(CLEAR_VARS)  
  2. LOCAL_MODULE := foo-prebuilt  
  3. LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libfoo.so  
  4. LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include  
  5. include $(PREBUILT_SHARED_LIBRARY)  
這裏假設要拷貝的預編譯庫所在的目錄結構以下:
    Android.mk            --> 編譯這個預編譯庫的Android.mk
    armeabi/libfoo.so     --> armeabi版本的共享庫
    armeabi-v7a/libfoo.so --> armeabi-v7a版本的共享庫
    include/foo.h         --> 預編譯庫導出的頭文件
注意:你沒必要提供armeabi-v7a版本,由於armeabi版本的共享庫可以被armeabi-v7a的兼容,可是反過來就不行。
相關文章
相關標籤/搜索