關(guān)于Android.mk你需要知道的

Android.mk

Android.mk是一個向Android NDK構(gòu)建系統(tǒng)描述NDK項(xiàng)目的GUN makefile片段。主要用來編譯生成以下幾種:

  • APK程序:一般的Android應(yīng)用程序,系統(tǒng)級別的直接push即可
  • JAVA庫:JAVA類庫,編譯打包生成JAR文件。
  • C\C++應(yīng)用程序:可執(zhí)行的C\C++應(yīng)用程序蠢棱。
  • C\C++靜態(tài)庫:編譯生成C\C++靜態(tài)庫
  • C\C++共享庫:編譯生成共享庫,并打包成.so文件

Android.mk基本格式

# 定義模塊當(dāng)前路徑(必須定義在文件開頭,只需定義一次)
# my-dir是編譯系統(tǒng)提供的宏函數(shù) 返回mk當(dāng)前路徑
LOCAL_PATH := $(call my-dir)

# 清空當(dāng)前環(huán)境變量(以LOCAL_開頭除LOCAL_PATH外變量)
# CLEAR_VARS是 GUN Makefile提供的一段特定的Makefile片段
# 這樣做因?yàn)榫幾g系統(tǒng)在單次執(zhí)行中會解析多個構(gòu)建文件和模塊定義禀忆,而LOCAL_開頭的變量是全局變量,所以落恼,描述每個模塊前都會做此操作箩退,避免沖突
include $(CLEAR_VARS)

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

# 當(dāng)前模塊包含的源代碼文件(多個用“空格”隔開)
LOCAL_SRC_FILES := hello-jni.c

# 表示當(dāng)前模塊將被編譯成一個共享庫
include $(BUILD_SHARED_LIBRARY)

編譯多個共享庫

一個Android可能編譯產(chǎn)生多個共享庫模塊。

會產(chǎn)生libmodule1.so和libmodule2.so兩個動態(tài)庫

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)

編譯靜態(tài)庫

雖然Android應(yīng)用程序不能直接使用靜態(tài)庫佳谦,但可以使用靜態(tài)庫編譯成動態(tài)庫戴涝。比如講三方代碼添加到原生項(xiàng)目中時(shí),可以不用直接將第三方源碼包括在原生項(xiàng)目中钻蔑,而是將三方源碼編譯成靜態(tài)庫啥刻,然后并入共享庫。

LOCAL_PATH := $(call my-dir)

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

# 原生模塊
include $(CLEAR_VARS)
LOCAL_MODULE := module
LOCAL_SRC_FILES := module.c
# 將靜態(tài)庫模塊名添加到LOCAL_STATIC_LIBRARIES變量
LOCAL_STATIC_LIBRARIES := avilib
include $(BUILD_SHARED_LIBRARY)

如果多個共享庫都是用到了avi庫咪笑,那么avi庫就是通用模塊可帽,我們可以使用共享庫共享通用模塊

使用共享庫共享通用模塊

靜態(tài)庫可以保證源代碼模塊化,但是當(dāng)靜態(tài)庫與共享庫相連時(shí)窗怒,它就變成了共享庫的一部分映跟。在多個共享庫的情況下,多個共享庫與靜態(tài)庫連接時(shí)扬虚,需要將通用模塊的多個副本與不同的共享庫重復(fù)相連申窘,這樣就增加了APP的大小。這種情況下可將通用模塊作為共享庫孔轴。

LOCAL_PATH := $(call my-dir)

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

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

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

以上所有的模塊必須屬于同一NDK項(xiàng)目剃法,如果是多個NDK項(xiàng)目間如何處理呢?

在多個NDK項(xiàng)目間共享模塊

從NDKr5開始允許多個NDK項(xiàng)目共享重用模塊路鹰,使用 improt-module

  1. 將avilib源代碼移動到NDK以外的位置贷洲,比如C:\android\shared-modules\transcode\avilib
  2. avilib創(chuàng)建自己的Android.mk文件
  3. import-module需要先定位共享模塊,然后導(dǎo)入到NDK項(xiàng)目中晋柱,默認(rèn)import-module只搜索NDK目錄下sources目錄优构。如果想要搜索到其他目錄需要定義新環(huán)境變量NDK_MODULE_PATH并且設(shè)置成共享模塊的根目錄.

示例

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

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

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

使用預(yù)編譯庫

當(dāng)我們想在不發(fā)布源代碼的情況下將模塊發(fā)布給他人;想使用共享模塊的預(yù)編譯版來加速編譯過程雁竞。這時(shí)候我們就可以使用預(yù)編譯庫

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

編譯獨(dú)立的可執(zhí)行文件

為了方便測試和進(jìn)行加速開發(fā)钦椭,可以編譯成可執(zhí)行文件拧额。不用打包成APK就可以復(fù)制到Android設(shè)備上執(zhí)行

# 獨(dú)立可執(zhí)行模塊的Android.mk文件
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := module
LOCAL_SRC_FILES := module.c
LOCAL_STATIC_LIBRARIES := avilib
include $(BUILD_EXECUTABLE)

注意事項(xiàng)

假如我們本地庫 libhello-jni.so依賴于libTest.so(可以使用NDK下的ndk-depends查看so的依賴關(guān)系)

  • Android6.0版本之前,需要在加載本地庫前先加載被依賴的so彪腔。
  • Android6.0版本之后侥锦,不能在使用預(yù)編譯的動態(tài)庫(靜態(tài)庫沒問題)。
// Android 6.0版本之前  libhello-jni.so依賴于libTest.so 需要先加載libTest.so
System.loadLibrary("Test");
System.loadLibrary("hello-jni");
// Android 6.0版本之后
System.loadLibrary("hello-jni");
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末德挣,一起剝皮案震驚了整個濱河市恭垦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌格嗅,老刑警劉巖番挺,帶你破解...
    沈念sama閱讀 206,723評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異屯掖,居然都是意外死亡玄柏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評論 2 382
  • 文/潘曉璐 我一進(jìn)店門贴铜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粪摘,“玉大人,你說我怎么就攤上這事阀湿「鲜欤” “怎么了瑰妄?”我有些...
    開封第一講書人閱讀 152,998評論 0 344
  • 文/不壞的土叔 我叫張陵陷嘴,是天一觀的道長。 經(jīng)常有香客問我间坐,道長灾挨,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,323評論 1 279
  • 正文 為了忘掉前任竹宋,我火速辦了婚禮劳澄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜈七。我一直安慰自己秒拔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評論 5 374
  • 文/花漫 我一把揭開白布飒硅。 她就那樣靜靜地躺著砂缩,像睡著了一般。 火紅的嫁衣襯著肌膚如雪三娩。 梳的紋絲不亂的頭發(fā)上庵芭,一...
    開封第一講書人閱讀 49,079評論 1 285
  • 那天,我揣著相機(jī)與錄音雀监,去河邊找鬼双吆。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的好乐。 我是一名探鬼主播匾竿,決...
    沈念sama閱讀 38,389評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼曹宴!你這毒婦竟也來了搂橙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,019評論 0 259
  • 序言:老撾萬榮一對情侶失蹤笛坦,失蹤者是張志新(化名)和其女友劉穎区转,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體版扩,經(jīng)...
    沈念sama閱讀 43,519評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡废离,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了礁芦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蜻韭。...
    茶點(diǎn)故事閱讀 38,100評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖柿扣,靈堂內(nèi)的尸體忽然破棺而出肖方,到底是詐尸還是另有隱情,我是刑警寧澤未状,帶...
    沈念sama閱讀 33,738評論 4 324
  • 正文 年R本政府宣布俯画,位于F島的核電站,受9級特大地震影響司草,放射性物質(zhì)發(fā)生泄漏艰垂。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評論 3 307
  • 文/蒙蒙 一埋虹、第九天 我趴在偏房一處隱蔽的房頂上張望猜憎。 院中可真熱鬧,春花似錦搔课、人聲如沸胰柑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,289評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽柬讨。三九已至,卻和暖如春急灭,著一層夾襖步出監(jiān)牢的瞬間姐浮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,517評論 1 262
  • 我被黑心中介騙來泰國打工葬馋, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卖鲤,地道東北人肾扰。 一個月前我還...
    沈念sama閱讀 45,547評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像蛋逾,于是被迫代替她去往敵國和親集晚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評論 2 345

推薦閱讀更多精彩內(nèi)容