1. 程式人生 > >cocos2d android分析之-libcocos2dlua.so庫

cocos2d android分析之-libcocos2dlua.so庫

首先把so動態庫檔案 編譯出來(通過NDK),然後再 拷貝到android的工程裡 libs/armeabi/下,如果libs/armeabi 不存在,那就自己建立,最後用eclipse編譯專案,這樣將自動把so檔案打包到apk裡;eclipse在打包的時候會根據檔案名的命名規則(lib****.so)去打包so檔案,開頭和結尾必須分別為“lib”和“.so”,否則是不會打包到apk檔案中的。

生成so檔案的規則參考Android.mk檔案:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)  清除變數

LOCAL_MODULE := cocos2dlua_shared  定義模組名

LOCAL_MODULE_FILENAME := libcocos2dlua  輸出的檔名字,所以會生成libcocos2dlua.so檔案

LOCAL_SRC_FILES := \
../../Classes/AppDelegate.cpp \   需要編譯的原始檔

hellolua/main.cpp

LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/../../Classes/protobuf-lite \
$(LOCAL_PATH)/../../Classes/runtime \
$(LOCAL_PATH)/../../Classes \
$(LOCAL_PATH)/../../../cocos2d-x/external \
$(LOCAL_PATH)/../../../cocos2d-x/tools/simulator/libsimulator/lib  

LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes   <span style="font-family: 'Microsoft YaHei', 微軟雅黑, Lucida, Verdana, 'Hiragino Sans GB', STHeiti, 'WenQuanYi Micro Hei', SimSun, sans-serif;">c檔案的搜尋路徑</span>


# _COCOS_HEADER_ANDROID_BEGIN
# _COCOS_HEADER_ANDROID_END

LOCAL_STATIC_LIBRARIES := cocos2d_lua_static
LOCAL_STATIC_LIBRARIES += cocos2d_simulator_static  依賴這兩個靜態庫

# _COCOS_LIB_ANDROID_BEGIN
# _COCOS_LIB_ANDROID_END

include $(BUILD_SHARED_LIBRARY)  生成 動態連結庫 so 檔案

$(call import-module,scripting/lua-bindings/proj.android)  指定靜態庫的搜尋路徑
$(call import-module,tools/simulator/libsimulator/proj.android)

# _COCOS_LIB_IMPORT_ANDROID_BEGIN
# _COCOS_LIB_IMPORT_ANDROID_END

是否所有的c檔案都編譯進來了呢?答案是肯定的。其他c檔案編譯進了其他靜態連結庫中,層層依賴,但最終都到了.so這個檔案中了。

在cocos2d android程式碼中對這個so進行了載入以便可以呼叫C++。

Cocos2dxActivity:

protected void onLoadNativeLibraries() {
        try {
            ApplicationInfo ai = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);
            Bundle bundle = ai.metaData;
            String libName = bundle.getString("android.app.lib_name");
            System.loadLibrary(libName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
經過一段時間的追尋,靜態庫依賴關係是這樣的:

cocos2dlua_shared-[cocos2d_lua_static,cocos2d_simulator_static]

cocos2d_lua_static-[cocos2d_lua_android_static,cocos2dx_static,pbc,dragonbones_static],pbc,dragonbones_static是自己新增進來的。

cocos2dx_static-[cocosbuilder_static,cocos3d_static,spine_static...lib_socket_static]

cocos2dx_internal_static這個包含了很多基本的類,但是它嵌入的還是蠻深的。

cocos2dx_internal_static--->cocos_extension_static--->cocos_ui_static--->cocostudio_static。

其實沒必要這麼較真的,反正都是各種依賴,但是找到了總算驗證了我們的答案,心裡踏實多了。

如何加入已經編譯好的靜態庫呢,這些庫就不需要我們去編譯了。

分析cocos2d中整合的curl庫吧。

檔案結構為:

curl

  --include 包含了所有的標頭檔案

  --prebuilt 包含了所有平臺的靜態庫

     --android 又是各種cpu型別

         ---armeabi  

         ---armeabi-v7a

         ---x86

 --- Android.mk

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := cocos_curl_static  庫名
LOCAL_MODULE_FILENAME := curl
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../include/android
LOCAL_STATIC_LIBRARIES += cocos_ssl_static 依賴的靜態庫
LOCAL_STATIC_LIBRARIES += cocos_crypto_static
include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := cocos_crypto_static
LOCAL_MODULE_FILENAME := crypto
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libcrypto.a
include $(PREBUILT_STATIC_LIBRARY)

LOCAL_MODULE := cocos_ssl_static
LOCAL_MODULE_FILENAME := ssl
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libssl.a
include $(PREBUILT_STATIC_LIBRARY)  

PREBUILT_SHARED_LIBRARY

該變數指向一個已編譯好的共享庫。與BUILD_SHARED_LIBRARY和BUILD_STATIC_LIBRARY不同,此時相應的LOCAL_SRC_FILES不再指定原始檔,而是指向這個預編譯共享庫檔案(例如 foo/libfoo.so)。可以在其他模組中,通過使用LOCAL_PREBUILTS變數來引用這個預編譯模組。

PREBUILT_STATIC_LIBRARY

與PREBUILT_SHARED_LIBRARY相同,只不過這裡是靜態庫。 

參考: