標籤:
原文網址:http://jeyechao.iteye.com/blog/2164286
ndk編譯出來的共用庫,eclipse會自動打包到apk中,而編譯出來的可執行檔則不會。
要想可執行檔自動被打包到apk中,可以把檔案名稱改成libxxx.so的形式,偽裝成so,這樣就會被打包進apk。
但是每次編譯之後都改一下名字,太麻煩!
寫個指令碼吧,又有arm, armv7, x86的麻煩事!
想試著改LOCAL_MODULE_FILENAME來試試,NDK又不允許。
於是稍微看了下NDK的編譯指令碼,發現如下解決辦法。
NDK是通過在Android.mk檔案中include $(BUILD_EXECUTABLE)來編譯可執行檔,其實就是調用了一個已經寫好的指令碼——build-executable.mk。(編譯指令碼都在NDK_ROOT/build/core目錄裡面)
仔細看指令碼的調用過程可以發現,指令碼一開始先檢查一下變數合法性(前面改LOCAL_MODULE_FILENAME的方法在這裡過不去),最終調用include$(BUILD_SYSTEM)/build-module.mk來編譯。
於是研究這個指令碼,找到決定編譯輸出的變數,在調用最終的編譯指令碼之前改成想要的就可以了。
最終我的方案如下:
1. 為了不破壞ndk本來的指令碼,將build-executable.mk拷貝一份放在自己的工程目錄下面,在倒數第三行插入一句 $(evalLOCAL_BUILT_MODULE := $(TARGET_OUT)/$(MY_LOCAL_MODULE_FILENAME))
2. 在自己的Android.mk檔案中定義MY_LOCAL_MODULE_FILENAME變數,當然值就是你想要的檔案名稱啦
3. 編譯時間不調用系統的include$(BUILD_EXECUTABLE), 而改調用自己的指令碼(就是上面拷貝出來且做了修改的那個指令碼),為了方便,你可以給自己的指令碼定義一個變數來指向它。
就是這樣。
寫得比較亂,貼幾段關鍵代碼吧。
修改後的build-executable.mk代碼。
Xml代碼
- LOCAL_BUILD_SCRIPT := BUILD_EXECUTABLE
- LOCAL_MAKEFILE := $(local-makefile)
-
- $(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
- $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
- $(call check-LOCAL_MODULE_FILENAME)
-
- # we are building target objects
- my := TARGET_
-
- $(call handle-module-filename,,)
- $(call handle-module-built)
-
- $(eval LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(MY_LOCAL_MODULE_FILENAME))
-
- LOCAL_MODULE_CLASS := EXECUTABLE
- include $(BUILD_SYSTEM)/build-module.mk
14行就是我們加的那一行。
上面的檔案放在jni根目錄,跟目錄下的Android.mk代碼:
Xml代碼
- MY_BUILD_EXECUTABLE := $(JNI_ROOT)/build-executable.mk
- include $(call all-subdir-makefiles)
需要編譯可執行檔的模組這樣寫:
Xml代碼
- LOCAL_PATH := $(call my-dir)
- include $(CLEAR_VARS)
-
- LOCAL_SRC_FILES := ...
- LOCAL_MODULE := xxx
- MY_LOCAL_MODULE_FILENAME := libxxx.so
- LOCAL_C_INCLUDES := ...
- LOCAL_LDLIBS:=-L$(SYSROOT)/usr/lib -llog
- LOCAL_CFLAGS := -fPIC
-
- include $(MY_BUILD_EXECUTABLE)
OK, 大功告成!
【轉】如何把ndk編譯出來的可執行檔偽裝成so打包到apk中