1.Android 編譯系統概述

②針對某個產品(一個產品可能是某個型號的手機或者平板電腦)的 Make 文件,這些文件通常位於 device 目錄下,該目錄下又以公司名以及產品名分為兩級目錄對於一個產品的定義通常需要一組文件,這些文件共同構成了對於這個產品的定義。
③第三類是針對某個模塊的 Make 文件。整個系統中,包含了大量的模塊,每個模塊都有一個專門的 Make 文件,這類文件的名稱統一為“Android.mk”,該文件中定義了如何編
譯當前模塊。Build 系統會在整個源碼樹中掃描名稱為“Android.mk”的文件並根據其中的內容執行模塊的編譯。
2.編譯Tiny4412 Android系統
編譯Android系統命令如下:
source build/envsetup.sh lunch full_tiny4412-eng make -j4
build/envsetup.sh
腳本。該腳本的作用是初始化編譯環境,並引入一些輔助的 Shell 函數,這其中就包括第二步使用 lunch 函
3.源碼編譯過程分析
整個 Build 系統的入口文件是源碼樹根目錄下的“Makefile”的文件,當在源代碼根目錄上調用 make 命令時,make 命令首先將讀取該文件。它的內容如下。
### DO NOT EDIT THIS FILE ### include build/core/main.mk ### DO NOT EDIT THIS FILE ###
它引用了 build/core/main.mk 文件。 main.mk 文件中又引用了其他.mk文件,其他.mk文件中又會包含更多的.mk文件,這樣就將了整個 Build 系統串聯起來了。
3.1 主要的 Make 文件的說明
文件名 | 說明 |
---|---|
main.mk | 最主要的 Make 文件,該文件中首先將對編譯環境進行檢查,同時引入其他的 Make 文件,設置全局變量 和幾個最主要的Make目標,比如Droid、sdk等 |
help.mk | 包含了名稱為 help 的 Make 目標的定義,該目標將列出主要的 Make 目標及其說明。 |
pathmap.mk | 將許多頭文件的路徑通過名值對的方式定義為映射表,並提供 include-path-for 函數來獲取。例如,通過$(call include-path-for, frameworks-native) 便可以獲取到 framework 本地代碼需要的頭文件路徑。 |
envsetup.mk | 配置 Build 系統需要的環境變量,例如:TARGET_PRODUCT,TARGET_BUILD_VARIANT,HOST_OS,HOST_ARCH 等。當前編譯的主機平台信息(例如操作系統,CPU 類型等信息)就是在這個文件中確定的。另外,該文件中還指定了各種編譯結果的輸出路徑。 |
combo/select.mk | 根據當前編譯器的平台選擇平台相關的 Make 文件。 |
dumpvar.mk | 在 Build 開始之前,顯示此次 Build 的配置信息。 |
config.mk | 整個 Build 系統的配置文件,最重要的 Make 文件之一。該文件中主要包含以下內容:
|
definitions.mk | 最重要的 Make 文件之一,在其中定義了大量的函數。這些函數都是 Build 系統的其他文件將用到的。例如:my-dir,all-subdir-makefiles,find-subdir-files,sign-package 等,關於這些函數的說明請參見每個函數的代碼注釋。 |
distdir.mk | 針對 dist 目標的定義。dist 目標用來拷貝文件到指定路徑。 |
dex_preopt.mk | 針對啟動 jar 包的預先優化。 |
pdk_config.mk | 顧名思義,針對 pdk(Platform Developement Kit)的配置文件。 |
${ONE_SHOT_MAKEFILE} |
ONE_SHOT_MAKEFILE 是一個變量,當使用“mm”編譯某個目錄下的模塊時,此變量的值即為當前指定路徑下的 Make 文件的路徑。 |
${subdir_makefiles} |
各個模塊的 Android.mk 文件的集合,這個集合是通過 Python 腳本掃描得到的。 |
post_clean.mk | 在前一次 Build 的基礎上檢查當前 Build 的配置,並執行必要清理工作。 |
legacy_prebuilts.mk | 該文件中只定義了 GRANDFATHERED_ALL_PREBUILT 變量。 |
Makefile | 被 main.mk 包含,該文件中的內容是輔助 main.mk 的一些額外內容。 |
3.2 主要Makefile的調用流程
l 初始化相關的參數設置(buildspec.mk、envsetup.mk、config.mk)
l 檢測編譯環境和目標環境
l 決定目標product
l 讀取product的配置信息及目標平台信息
l 清除輸出目錄
l 檢查版本號
l 讀取Board的配置
l 讀取所有Module的配置
l 根據配置產生必要的規則(build/core/Makefile)
l 生成image
①main.mk:它是整個系統編譯系統主導文件,它的主要內容如下
#定義默認的target即make命令后不加參數的默認目標 # This is the default target. It must be the first declared target. .PHONY: droid DEFAULT_GOAL := droid $(DEFAULT_GOAL): #引入help.mk,help.mk 包含了名稱為 help 的 Make 目標的定義, #該目標將列出主要的 Make 目標及其說明 # Targets that provide quick help on the build system. include $(BUILD_SYSTEM)/help.mk #引入config.mk,定義產品,主機的各種基本變量 # Set up various standard variables based on configuration # and host information. include $(BUILD_SYSTEM)/config.mk #引入clean操作的定義 # This allows us to force a clean build - included after the config.mk # environment setup is done, but before we generate any dependencies. This # file does the rm -rf inline so the deps which are all done below will # be generated correctly include $(BUILD_SYSTEM)/cleanbuild.mk #引入基本編譯系統的定義,提供了大量的實用函數 # Bring in standard build system definitions. include $(BUILD_SYSTEM)/definitions.mk #讀取android源碼樹中所有的Android.mk ifneq ($(dont_bother),true) # # Include all of the makefiles in the system # # Can't use first-makefiles-under here because # --mindepth=2 makes the prunes not work. 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)))
②config.mk解析:產品配置主導文件
#引入envsetup.mk定義大部分全局變量,配置編譯時的環境變量。 #該文件可以指定用戶編譯配置 # --------------------------------------------------------------- # Define most of the global variables. These are the ones that # are specific to the user's build configuration. include $(BUILD_SYSTEM)/envsetup.mk
③envsetup.mk:用來配置編譯時的環境變量
#引入BoardConfig.mk,BoardConfig.mk主要寫了product使用的硬件所支持和不支持的功能性內容。 #BroadConfig.mk設置了每個設備的自己的一些變量值,來區別編譯時的行為 include $(board_config_mk) ...... # Boards may be defined under $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE) # or under vendor/*/$(TARGET_DEVICE). Search in both places, but # make sure only one exists. # Real boards should always be associated with an OEM vendor. board_config_mk := \ $(strip $(wildcard \ $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk \ $(shell test -d device && find device -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \ $(shell test -d vendor && find vendor -maxdepth 4 -path '*/$(TARGET_DEVICE)/BoardConfig.mk') \ )) #設置版本信息 # Set up version information. include $(BUILD_SYSTEM)/version_defaults.mk #引入產品級別的配置 # Read the product specs so we can get TARGET_DEVICE and other # variables that we need in order to locate the output files. include $(BUILD_SYSTEM)/product_config.mk
④product_config.mk:產品級別的配置,讀取指定的目錄下所有的AndrodProducts.mk文件中定義的產品信息
#引用AndroidProducts.mk #讀取AndrodProducts.mk文件中定義的產品信息 ifneq ($(strip $(TARGET_BUILD_APPS)),) # An unbundled app build needs only the core product makefiles. all_product_configs := $(call get-product-makefiles,\ $(SRC_TARGET_DIR)/product/AndroidProducts.mk) else # Read in all of the product definitions specified by the AndroidProducts.mk # files in the tree. all_product_configs := $(get-all-product-makefiles) endif