Android.mk是Android工程管理文件,其作用基本等同於Linux環境中的Makefile,在語法上,Android.mk和普通Makefile略有不同,主要區別是Android.mk包含一些Android編譯系統的公共的宏
Android.mk中選項參考以下文件路徑:
build/core/config.mk
各個選項的默認值在以下文件中定義:
build/core/base_rules.mk
1、Android.mk文件只處理從根目錄開始找到的第一個Android.mk文件,如果需要遞歸。需要在當前目錄的Android.mk文件中做如下處理:
include $(call all-makefiles-under,$(LOCAL_PATH))
在一個Android.mk中也可以生成多個目標:可執行程序,動態庫,靜態庫或者Android用用程序包
Android.mk文件可以處理多個內容:
include $(CLEAR_VARS) //清理變量
#處理第一個內容
include $(CLEAR_VARS)
#處理第二個內容
現在我們來討論對於各種目標的構建方式
1、
可執行程序
LOCAL_PATH :=$(my_dir) //本地路徑,當前目錄
Text EXe
include $(CLEAR_VARS)
LOCAL_SRC_FILES := eng
LCAOL_SRC_FILES :=\
main.c
LOCAL_MODULE := text_exe
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := libc
include $(BUILD_EXECUTABLE)
注:編譯一個可執行程序,需要在LOCAL_SRC_FILES 中假如遠見路徑(相對於當前Android.mk目錄的路徑),
在LOCAL_C_INCLUDES中假如所需要包含的頭文件路徑;
在LOCAL_STATIC_LIBRARIES 中假如所需要鏈接的靜態庫(*.a)的名稱
在LOCAL_SHARED_LIBRARIES中假如所需要鏈接的動態庫(*.so)的名稱
LOCAL_MODULE標示模塊最終的名稱,最后使用include$(build_executable)
表示以一個可執行程序的方式進行編譯,在本例中,LOCAL_MODULE被定義為test_exe,
因此最終生成可執行程序的名稱是test_exe
一個可執行程序編譯后生成獨立的目標目錄在out/target/product/中,路徑如下所示:
<TARGET_PRODUCT>/obj/EXECUTABLES/<LOCAL_MODULE>
2、靜態庫
靜態庫,也稱之為歸檔文件,在Linux中擴展名通常為.a,在Android.mk中編譯一個靜態庫(歸檔文件)的模板如下所示
LOCAL_PATH :=$(my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_SRC_FILES :=\
hello.c
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBARIES :=
LOCAL_SHARED_LIBRARAIES := libc
include $(BUILD_STATIC_LIBRARY)
在編譯靜態庫,基本的內容和編譯可執行程序相似,區別在於include$(BUILD_STATIC_LIBRARY) 標示編譯靜態庫。在本例中,LOCAL_MODULE被定義為libtest_static,因此最終生成的靜態庫的名稱是libtest_static.a
3、動態庫
動態庫 也稱之為共享庫,是linux標准的elf格式文件的一種,在Linux中擴展名通常為.so在Android中編譯一個動態庫(共享庫)的模板如下:
LOCAL_PATH := $(my-dir)
LOCAL_PATH := $(my-dir)
include $ (CLEAR_VARS)
LOCAL_MODULE_TAGS :=eng
LOCAL_SRC_FILES := \
hello.c
LOCAL_MODULE := libtest_stared
TARGET_PRELINK_MODULE := false
LOCAL_C_INCLUDES :=
LOCAL_STATIC_LIBRARIES :=
LOCAL_SHARED_LIBRARIES := libc
include $ (BUILD_SHARED_LIBRARY)
編譯一個動態庫,基本的內容和編譯可執行程序、靜態庫相似,區別在於使用include$(BUILD_SHARED_LIBRARY)
表示編譯動態庫。在本例中,LOCAL_MODULE被定義為libtest_shared,因此最終生成的動搖庫的名稱是libtest_shared.so
一個動態庫編譯后生成的獨立的目標目錄在out/target/product/中,路徑如下所示
<TARGET_PRODUCT>/obj/STATIC_LIBRARIES/<LOCAL_MODULE>
Android 應用程序包是一種特殊的文件,通常以apk為擴展名。在Android.mk中編譯
一個應用程序包的模板如下所示:
LOCAL_PATH := $(CALL my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_PACKAGE_NAME := TestApplication
include $(BUILD_PACKAGE)
這里使用BUILD_PACKAGE宏表示編譯apk,而LOCAL_SRC_FILES 使用自動查找的方法,將找打所有的java文件進行編譯
在源代碼環境中編譯和在SDK中編譯應用程序包略有不同,涉及的目錄主要有一下兩個。
out/target/common/obj/APPS: 通用java字節碼目錄
out/target/product/<TARGET_PRODUCT>obj/APPS:Android 應用包目錄
每個包在兩個目錄中均具有名為{LOCAL_PACKAGE_NAME}_intermediates/的獨立目錄
例如,對於SkeletonApp包編譯,公共目錄的生成結構如下所示:
關於在編譯應用程序的時候,有一個額外的宏可以控制編譯的行為,如下所示:
WITH_DEXPREOPT := true
如果WITH_DEXPREOPT 被定義為true,一個應用程序將由兩個部分組成:一個是不包含java字節碼classes.dex的apk文件,一個是名稱為classes.odex的字節碼文件。
兩個文件同時預制在系統中依然可以構成能運行的應用程序。但是,這種生成的結構就不能在進行動態的安裝了。
Android4.x以上默認為true
