首先, 編譯Android 代碼 通常情況下使用:
# make showcommands
這實際上等價於下面的完整命令 (具體參見 build/core/envsetup.mk )
# TARGET_ARCH=arm TARGET_PRODUCT=generic TARGET_BUILD_TYPE=release make showcommands
可見,默認情況下編譯系統認為TARGET_PRODUCT 是generic 的
那如何編譯特定產品的Android呢?
這就需要查看Android Makefile是如何解析環境變量TARGET_PRODUCT的。
Android Makefile 的引用關系是這樣的
Makefile -> build/core/main.mk -> build/core/config.mk -> build/core/envsetup.mk -> build/core/product_config.mk
在build/core/product_config.mk 中編譯系統首先調用 build/core/product.mk中定義的函數get-all-product-makefiles ,來
遍歷整個vendor 的子目錄, 找到vendor下所有的 AndroidProducts.mk, 不同子目錄下的AndroidProducts.mk 中定義了不同的 PRODUCT_NAME, PRODUCT_DEVICE 等信息,(我們也可以通過 打開build/core/product_config.mk 中的#$(dump-products) 語句使控制臺編譯的時候輸出所有product 的信息) , 接著build/core/product_config.mk 會調用resolve-short-product-name 將TARGET_PRODUCT匹配的AndroidProducts.mk 中定義的 PRODUCT_DEVICE 賦值給TARGET_DEVICE。
有了這個TARGET_DEVICE, 再回到 build/core/config.mk,
會include $(TARGET_DEVCIE)/BoardConfig.mk
board_config_mk := /
$(strip $(wildcard /
$(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk /
vendor/*/$(TARGET_DEVICE)/BoardConfig.mk /
))
include $(board_config_mk)
而這個配置文件BoardConfig.mk 決定了目標系統編譯屬性,比如使用ALSA還是不是 GENERIC_AUDIO 等等
另外在這裏TARGET_DEVICE 宏也決定了TARGET_DEVICE_DIR, 因為TARGET_DEVICE_DIR 取的是上面提到的BoardConfig.mk 的路徑。
TARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk)))
當然Android 的Ob目標輸出也是由TARGET_DEVICE決定,見build/core/envsetup.mk
TARGET_OUT_ROOT_release := $(OUT_DIR)/target
TARGET_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/target
TARGET_OUT_ROOT := $(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE))
TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
再回到 build/core/main.mk, 編譯系統接著做的壹個件事情是,遍歷所有字目錄,找到所有Android.mk文件,並將這些Android.mk文件include 進來
#
# Typical build; include any Android.mk files we can find.
#
subdir_makefiles := /
$(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)
include $(subdir_makefiles)
我們再來看其中的
./build/target/board/Android.mk
,對了它引用了
include $(TARGET_DEVICE_DIR)/AndroidBoard.mk
由上面TARGET_DEVICE_DIR的定義,這下又進入了
vendor 下TARGET_DEVICE指向的目錄了,這個mk文件中定義了特定Product需要編譯和安裝app 和 script.