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相同,只不過這裡是靜態庫。
參考: