Android MK詳解

說到.mk文件,看多android源碼的童鞋會發現其中存在着繁多的mk文件。一開始不知道是幹什麼的,後來才發現這是android源碼正常編譯工作的大功臣。

習慣開發APP的童鞋,配套使用一定是一款自己拿手的IDE。那對於android源碼來說,配套使用的就是一整套mk文件。android源碼複雜,由不同功能的文件夾組成,幾乎每個模塊的根路徑下都有一個mk文件,android系統在編譯的時候,就會根據這個mk文件對此模塊進行定製化編譯。是需要編譯哪些內容,依賴什麼,編譯得到什麼,mk這種規則文件都很好的制定一個模塊編譯階段該幹什麼。mk文件還有個突出的優點,叫自動化,既然訂好了規則,編譯的時候對於每個模塊只要執行編譯就好了,像多米諾骨牌,全盤結束。

常見的編譯類型有編譯出apk,編譯出jar,編譯出二進制可執行文件,編譯出.so庫文件等等

1

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)

LOCAL_PACKAGE_NAME := Settings

LOCAL_MODULE_TAGS := tests

LOCAL_CERTIFICATE := platform

LOCAL_STATIC_JAVA_LIBRARIES := jarlib1 jarlib2 jarlib3

LOCAL_SRC_FILES := $(call all-java-files-under, src)

LOCAL_JAVA_LIBRARIES := \
    com.mstar.android \
    com.cultraview.tv


include $(BUILD_PACKAGE)
##################################################
include $(CLEAR_VARS)

LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := jarlib1:libs/jsoup-1.7.2.jar \
                                        jarlib2:libs/android-support-v4.jar \
					jarlib3:libs/setting.jar

include $(BUILD_MULTI_PREBUILT)
編譯.apk文件,mk中需要註明include $(BUILD_PACKAGE),前二句正常開頭,制定當前目錄,清空變量。第三句指定應用名,第四句指定編譯類型(debug or release)備註tests爲debug模式,忽視waring,正常編譯,否則佈局中有android:text=“XXX”,沒有引用string.xml的資源,會直接報錯。第四句爲引入靜態鏈接庫,導入項目libs下三方jar(此處可以留意引入靜態鏈接庫的寫法,第5句和倒數###後需要一起書寫)第6句指定需要對項目中哪些文件進行編譯,第7句指定動態鏈接庫,一般爲源碼中jar的名。

2.

LOCAL_PATH:= $(call my-dir)

# the library
# ============================================================
include $(CLEAR_VARS)

LOCAL_SRC_FILES := $(call all-java-files-under, src)
            
LOCAL_MODULE := android.policy

# MStar Android Patch Begin
# CTV Patch Begin
LOCAL_JAVA_LIBRARIES := com.mstar.android \
                        com.cultraview.tv
# CTV Patch End
# MStar Android Patch End

include $(BUILD_JAVA_LIBRARY)

# additionally, build unit tests in a separate .apk
include $(call all-makefiles-under,$(LOCAL_PATH))

編譯jar,mk中需要註明include $(BUILD_JAVA_LIBRARY),這邊說下第4句local module寫明爲android.policy,那最後out下生成的jar,就會看到是android.policy.jar。還有最後一句,如果要生成單元測試apk,那可以寫最後一句。

3.

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
	dumpsys.cpp

LOCAL_SHARED_LIBRARIES := \
	libutils \
	liblog \
	libbinder
	

ifeq ($(TARGET_OS),linux)
	LOCAL_CFLAGS += -DXP_UNIX
	#LOCAL_SHARED_LIBRARIES += librt
endif

LOCAL_MODULE:= dumpsys

include $(BUILD_EXECUTABLE)

編譯二進制可執行文件,比如熟悉的dumpsys指令,mk中需要註明include $(BUILD_EXECUTABLE),其中有意思的一點是mk中執行各種簡單邏輯代碼比如if。

4.

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libeffectproxy
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
LOCAL_MODULE_TAGS := optional


LOCAL_SRC_FILES := \
        EffectProxy.cpp

LOCAL_CFLAGS+= -fvisibility=hidden

LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libdl libeffects

LOCAL_C_INCLUDES := \
        system/media/audio_effects/include \
        bionic/libc/include \
        frameworks/av/media/libeffects/factory

include $(BUILD_SHARED_LIBRARY)

編譯so庫文件,需要註明include $(BUILD_SHARED_LIBRARY)。

講了那麼多例子,無非是將不同場景中mk的用途稍微展示了下,當然mk還能做更多的作用,這裏不一一列出,隨便對源碼的研究深入,對mk的理解也會加深。

這裏再提一個mk的深入研究,mk之間是如何連串起來工作的,哪個是第一個mk,第一個mk的作用。

在android源碼根路徑下有個makefile文件,不同於普通.mk文件,它只有一句話include build/core/main.mk,也就意味主入口,mk的相關代碼都在build/core下.

Android Makefile 的引用關係是這樣的

Makefile -> build/core/main.mk -> build/core/config.mk -> build/core/envsetup.mk -> build/core/product_config.mk
這裏簡單提及一下,main.mk主要做了一些檢查工作,使用什麼shell,用什麼編譯,確定當前路徑等,接下來交給config.mk,它對普通mk文件意義非凡,比如之前看到的SRC等屬性,都是由config.mk來解析,具體工作。envsetup.mk主要對於編譯的SDK版本等一些做一個設定。product_config.mk主要引出對device.mk等的編譯。
至於爲什麼能一層一層,像多米諾骨牌一樣自動,源於mk中的一句話include $(call all-subdir-makefiles) 每當遇到這句,意味着make還需要繼續找下一級目錄下mk文件,繼續執行。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章