android.mk 比较字变量,粉丝投稿 | 谈谈Android.mk
原標(biāo)題:粉絲投稿 | 談?wù)凙ndroid.mk
本文由公號【你看上去真美】(微信號:tmac_lover)粉絲投稿,目前工作是Android系統(tǒng)rom定制開發(fā),有同行可以關(guān)注一下。
1. 為什么是Android.mk
不知道有沒有人想過,Android源碼里為什么每個(gè)模塊的編譯文件叫Android.mk? 而不是別的什么名字呢。這是因?yàn)閙ain.mk明確指定了,以每個(gè)子目錄下的Android.mk作為模塊編譯的起始makfile文件。
[build/core/main.mk]
subdir_makefiles := $(shell build/tools/findleaves.py --prune=$(OUT_DIR) --prune=.repo --prune=.git $(subdirs) Android.mk) $(foreach mk, $(subdir_makefiles), $(info including $(mk) ...)$(eval include $(mk)))
所以在Android源碼里,我們每次看一個(gè)模塊是如何編譯時(shí),總是把模塊所在目錄里的Android.mk作為編譯的起始Makefile文件。
2. 如何閱讀Android.mk
可能有朋友在琢磨是不是Android的編譯系統(tǒng)重新定義了一套和GNU Makefile完全不同的規(guī)則?答案是否定的。其實(shí)在編譯源碼時(shí),無論是直接使用make全編,還是使用mmmmm命令全編譯單個(gè)模塊,我們所遵循的原則和GNU Makefile是一模一樣的,最終都是使用相同的make命令,所有GNU Makefile規(guī)則在Android源碼里照樣適用,只不過Android封裝了寵大且復(fù)雜的編譯系統(tǒng),使得我們可以清晰簡便的做修改。
對于Android源碼的build系統(tǒng),比較復(fù)雜,涉及的知識點(diǎn)也相對較多,這里只以Android.mk作為切入點(diǎn),剩下的以后有機(jī)會(huì)展開,由點(diǎn)及面,對build系統(tǒng)熟悉起來。
以Android源碼里一個(gè)系統(tǒng)APP的Android.mk文件作為例子:
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-files-under, src) src/com/android/music/IMediaPlaybackService.aidl LOCAL_PACKAGE_NAME := Music LOCAL_PROGUARD_FLAG_FILES := proguard.flags include $(BUILD_PACKAGE)
具體解釋如下:
每一個(gè)Androi.mk文件都必須以定義LOCAL_PATH變量開頭,my-dir是由build系統(tǒng)定義的函數(shù),作用是返回當(dāng)前Android.mk在源碼中目錄
CLEARVARS是由build系統(tǒng)所定義的一個(gè)變量,它的值是build/core/clear_vars.mk,作用是清除很多LOCAL開頭的變量,但是不清理LOCAL_PATH,所以你可以當(dāng)include $(CLEAR_VARS)作為每個(gè)模塊編譯的開始。
LOCAL_MODULE_TAGS用于定義當(dāng)前模塊在什么編譯模式中被編譯,它的值有eng, user, tests, optional。
LOCAL_PACKAGE_NAME變量指明了編譯出apk的名字,只有當(dāng)前模塊是一個(gè)應(yīng)用(APP)才使用LOCAL_PACKAGE_NAME; 其余情況,無論so或jar包,全部都使用LOCAL_MODULE變量。
LOCAL_SRC_FILES變量指明編譯使用的源碼文件,all-java-files-under是由build系統(tǒng)定義的函數(shù),作用是列出指定目錄下所有的java文件。
LOCAL_PROGUARD_FLAG_FILES指定混淆文件,上例中表明當(dāng)前目錄下proguard.flags作為混淆文件。
BUILD_PACKAGE也是由build系統(tǒng)定義的一個(gè)變量,值是build/core/package.mk, 表示編譯出一個(gè)apk文件。一般來講,類似include $(BUILD_PACKAGE)可以作為一個(gè)模塊編譯的結(jié)束。
和BUILD_PACKAGE變量類似的還有好幾個(gè),這里列出其中常見的一部分:
BUILD_JAVA_LIBRARY — build/core/java_library.mk; 表示編譯一個(gè)jar包, 里面是DEX格式的文件
BUILD_STATIC_JAVA_LIBRARY – build/core/static_java_library.mk; 也編譯一個(gè)jar包,但是里面每個(gè)java文件所對應(yīng)的class文件都存在
BUILD_EXECUTABLE — build/core/executable.mk; 編譯一個(gè)可執(zhí)行的bin程序
BUILD_PREBUILT — build/core/prebuilt.mk;用于集成第三方的jar包或者so庫等
3. 常見變量
LOCAL_STATIC_JAVA_LIBRARIES/LOCAL_JAVA_LIBRARIES - 指明編譯當(dāng)前模塊所依賴的jar包
LOCAL_CERTIFICATE := platform - 指明使用platform key來對當(dāng)前模塊進(jìn)行簽名
LOCAL_AAPT_FLAGS - Android源碼里使用aapt打包jar包或apk文件,這個(gè)變量可以定義aapt打包參數(shù),比如 :—auto-add-overlay, —extra-packages
LOCAL_PROGUARD_ENABLED - 是否進(jìn)行混淆
4. 調(diào)試手段
我們調(diào)試代碼的時(shí)候,最常用的手段就是打log, 在不明白的地方,或者不知道走了哪個(gè)if分支,或者想看看變量的值是什么,都可以打log看。
Android build系統(tǒng)里也可以打Log,使用函數(shù)warning / info / error。
需要注意的是,error函數(shù)會(huì)讓編譯直接停下來,所以一般用warning和info
使用示例(以warning為例,其它兩個(gè)類似):
打印普通字符串(hello world):$(warning hello world)
打印變量的值:$(warning $(LOCAL_PACKAGE_NAME))
變量和字符串組合打印:$(warning thisapk is $(LOCAL_PACKAGE_NAME))
下面以一個(gè)真實(shí)的App編譯為例,在這個(gè)Android.mk里,可能我不知道PLATFORM_VERSION的值,所以我不知道它會(huì)不會(huì)進(jìn)ifeq語句,這時(shí)打個(gè)log, 編譯一下:
include $(CLEAR_VARS)... ...$(warning tmac_lover $(PLATFORM_VERSION))ifeq ($(PLATFORM_VERSION), 6.0) LOCAL_STATIC_JAVA_LIBRARIES += upgrade_httpclientendif... ...include $(BUILD_PACKAGE)
使用mm -B命令編譯apk, 從編譯輸出中可以看到下面這些,6.0就是PLATFORM_VERSION的值。
packages/apps/TVUpdate/Android.mk:29: tmac_lover 6.0
完。
本公號介紹
責(zé)任編輯:
總結(jié)
以上是生活随笔為你收集整理的android.mk 比较字变量,粉丝投稿 | 谈谈Android.mk的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android 9.0 https 适配
- 下一篇: Android面试题Service,An