Android.mk介紹

1.簡介

1.Android.mk是一個向Android NDK構建系統描述NDK項目的GNU makefile片段。主要用來編譯生成一下幾種:
	1.APK程序:一般的Android應用程序,系統級別的直接push即可。
	2.JAVA庫:JAVA類庫,編譯打包生成jar文件。
	3.C\C++應用程序:可執行的C\C++應用程序。
	4.C\C++靜態庫:編譯生成C\C++靜態庫,並打包成.a文件。
	5.C\C++共享庫:編譯生成共享庫,並打包成.so文件。

2.案例

# 定義當前模塊路徑 (必須定義在文件開頭,只需定義一次)
LOCAL_PATH := $(call my-dir)

# 清空當前環境變量 (LOCAL_PATH除外)
include $(CLEAR_VARS)

# 當前模塊名 (這裏會生成libhello-jni.so)
LOCAL_MODULE := hello-jni

# 當前模塊包含的源代碼文件
LOCAL_SRC_FILES := hello-jni.c

# 生成一個動態庫(表示當前模塊被編譯成一個共享庫)
include $(BUILD_SHARED_LIBRARY)

3.編譯多個共享庫

一個Android.mk可能編譯產生多個共享庫模塊,如下產生了libmodule1.so 和 libmodule2.so兩個庫
LOCAL_PATH := $(call my-dir)

#模塊1
include $(CLEAR_VARS)
LOCAL_MODULE := module1
LOCAL_SRC_FILES := module1.c
include $(BUILD_SHARED_LIBRARY)

#模塊2
include $(CLEAR_VARS)
LOCAL_MODULE := module2
LOCAL_SRC_FILES := module2.c
include $(BUILD_SHARED_LIBRARY)

4.編譯靜態庫

Android應用程序不能直接使用靜態庫,但是靜態庫可以用來編譯成動態庫。比如在將第三方代碼添加到原生項目中時,
可以不用直接將第三方源碼包含在原生項目中,而是將第三方源碼編譯成靜態庫,然後併入共享庫

LOCAL_PATH := $(call my-dir)

# 第三方庫AVI
include $(CLEAR_VARS)
LOCAL_MODULE := AVI
LOCAL_SRC_FILES := AVI.c
include $(BUILD_STATIC_LIBRARY)

#原生模塊
include $(CLEAR_VARS)
LOCAL_MODULE := module
LOCAL_SRC_FILES := module.c
#將靜態庫模塊名添加到LOACAL_STATIC_LIBRARIES變量
LOCAL_STAITC_LIBRAYIES := AVI
include $(BUILD_SHARED_LIBRARY)

5.使用共享庫共享通用模塊

靜態庫可以保證源代碼模塊化,但是當靜態庫與共享庫相連時,它就變成了共享庫的一部分。在多個共享庫的情況下,
多個共享庫與靜態庫連接時,需要將通用模塊的多個副本與不同的共享庫重複相連,這樣就增加了app的大小,這種
情況,可以將通用模塊作爲共享庫。

LOCAL_PATH := $(call my-dir)

# 第三方庫AVI
include $(CLEAR_VARS)
LOCAL_MODULE := AVI
LOCAL_SRC_FILES := AVI.c
include $(BUILD_SHARED_LIBRARY)

#原生模塊1
include $(CLEAR_VARS)
LOCAL_MODULE := module1
LOCAL_SRC_FILES := module1.c
LOCAL_SHARED_LIBRARIES := AVI
include $(BUILD_SHARED_LIBRARY)

#原生模塊2
include $(CLEAR_VARS)
LOCAL_MODULE := module2
LOCAL_SRC_FILES := module2.c
LOCAL_SHARED_LIBRARIES := AVI
include $(BUILD_SHARED_LIBRARY)

6.在多個NDK項目間共享模塊

1.首先將AVI源代碼移動到NDK項目以外的位置
2.作爲共享模塊,AVI需要有自己的Android.mk模塊
3.以transcode/avilib爲參數調用函數宏import-module添加到NDK項目的Android.mk文檔末尾

#AVI模塊自己的Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := AVI
LOCAL_SRC_FILES := AVI.c
include $(BUILD_SHARED_LIBRARY)

#使用共享模塊的NDK項目1的Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := module1
LOCAL_SRC_FILES := module1.c
LOCAL_SAHRED_LIBRARIES := AVI
include $(BUILD_SHARED_LIBRARY)
$(call import-module, transcode/AVI)

#使用共享模塊的NDK項目2的Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := module2
LOCAL_SRC_FILES := module2.c
LOCAL_SAHRED_LIBRARIES := AVI
include $(BUILD_SHARED_LIBRARY)
$(call import-module, transcode/AVI)

7.使用預編譯庫

1.想在不發佈源代碼的情況下降模塊發佈給他人
2.想使用共享模塊的預編譯版來加速編譯過程

#使用預編譯共享模塊的Android.mk文件
LOCAL_PATH := $(call my-dir)
#第三方預編譯庫
include $(CLEAR_VARS)
LOCAL_MODULE := AVI
LOCAL_SRC_FILES := libAVI.so
include $(PREBUILD_SHARED_LIBRARY)

8.編譯獨立的可執行文件

1.爲了方便測試和進行快速開發,可以編譯成可執行文件。不用打包成apk就可以複製到Android設備上直接執行
#獨立可執行模塊的Andriod.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := module
LOCAL_SRC_FILES := module.c
LOCAL_STAITC_LIBRAYIES := AVI
include $(BUILD_EXECUTABLE)

9.注意事項

1.假如我們本地庫libhello-jni.so依賴於libTest.so(可以使用NDK下的ndk-depends查看so的依賴關係)
2.在Android 6.0版本之前,需要在加載本地庫前先加載被依賴的so
3.在Android6.0版本之後,不能再使用預編譯的動態庫(靜態庫沒問題)

# Android 6.0版本之前:
System.loadLibrary("Test");
System.loadLibrary("hello-jni");

# Android 6.0版本之後:
System.loadLibrary("hello-jni");
發佈了126 篇原創文章 · 獲贊 12 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章