1、get_abs_build_var() 和 get_build_var()的實現都在build/envsetup.sh中。
2、在buld目錄下grep這兩個函數可知:這兩個函數只在build/envsetup.sh腳本中使用。
言歸正傳,貼代碼
# Get the value of a build variable as an absolute path.
function get_abs_build_var()
{
T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
fi
(\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
command make --no-print-directory -f build/core/config.mk dumpvar-abs-$1)
}
# Get the exact value of a build variable.
function get_build_var()
{
T=$(gettop)
if [ ! "$T" ]; then
echo "Couldn't locate the top of the tree. Try setting TOP." >&2
return
fi
(\cd $T; CALLED_FROM_SETUP=true BUILD_SYSTEM=build/core \
command make --no-print-directory -f build/core/config.mk dumpvar-$1)
}
這兩個shell函數的實現很相似,都是通過make指定build/core/config.mk文件,唯一不同的地方是target目標不同。
接下來我們分析config.mk文件。
config.mk文件開頭的註釋:
# This is included by the top-level Makefile.
# It sets up standard variables based on the
# current configuration and platform, which
# are not specific to what is being built.
根據註釋,我們可知config.mk文件主要是配置變量。
而且,config.mk 文件最後一行包含的$(BUILD_SYSTEM)/dumpvar.mk用於獲取一些變量。
接下來我們分析dumpvar.mk文件。
# ---------------------------------------------------------------
# the setpath shell function in envsetup.sh uses this to figure out
# what to add to the path given the config we have chosen.
ifeq ($(CALLED_FROM_SETUP),true) # 在get_abs_build_var() 和 get_build_var()函數中,CALLED_FROM_SETUP=true,走if分支。
ifneq ($(filter /%,$(HOST_OUT_EXECUTABLES)),)
# HOST_OUT_EXECUTABLES變量是在envsetup.mk文件中設置的。
ABP:=$(HOST_OUT_EXECUTABLES)
else
ABP:=$(PWD)/$(HOST_OUT_EXECUTABLES)
endif
ANDROID_BUILD_PATHS := $(ABP) # 應該是 out/host/linux-x86/bin
ANDROID_PREBUILTS := prebuilt/$(HOST_PREBUILT_TAG)
# HOST_PREBUILT_TAG變量是在envsetup.mk文件中設置的。應該是 linux-x86
ANDROID_GCC_PREBUILTS := prebuilts/gcc/$(HOST_PREBUILT_TAG)
# The "dumpvar" stuff lets you say something like
#
# CALLED_FROM_SETUP=true \
# make -f config/envsetup.make dumpvar-TARGET_OUT
# or
# CALLED_FROM_SETUP=true \
# make -f config/envsetup.make dumpvar-abs-HOST_OUT_EXECUTABLES
#
# The plain (non-abs) version just dumps the value of the named variable.
# The "abs" version will treat the variable as a path, and dumps an
# absolute path to it.
#
dumpvar_goals := \
$(strip $(patsubst dumpvar-%,%,$(filter dumpvar-%,$(MAKECMDGOALS))))
# MAKECMDGOALS 變量就是傳進來的目標dumpvar-abs-$1或 dumpvar-$1。
ifdef dumpvar_goals
ifneq ($(words $(dumpvar_goals)),1)
$(error Only one "dumpvar-" goal allowed. Saw "$(MAKECMDGOALS)")
endif
# If the goal is of the form "dumpvar-abs-VARNAME", then
# treat VARNAME as a path and return the absolute path to it.
absolute_dumpvar := $(strip $(filter abs-%,$(dumpvar_goals)))
ifdef absolute_dumpvar
dumpvar_goals := $(patsubst abs-%,%,$(dumpvar_goals))
ifneq ($(filter /%,$($(dumpvar_goals))),)
DUMPVAR_VALUE := $($(dumpvar_goals))
else
DUMPVAR_VALUE := $(PWD)/$($(dumpvar_goals))
endif
dumpvar_target := dumpvar-abs-$(dumpvar_goals)
else
DUMPVAR_VALUE := $($(dumpvar_goals))
dumpvar_target := dumpvar-$(dumpvar_goals)
endif
.PHONY: $(dumpvar_target)
$(dumpvar_target):
@echo $(DUMPVAR_VALUE)
# DUMPVAR_VALE其實就是dumpvar-$1中的$1變量的值。
endif # dumpvar_goals
ifneq ($(dumpvar_goals),report_config)
# PRINT_BUILD_CONFIG 在envsetup.mk中被定義爲true
PRINT_BUILD_CONFIG:=
endif
endif # CALLED_FROM_SETUP
ifneq ($(PRINT_BUILD_CONFIG),)
HOST_OS_EXTRA:=$(shell python -c "import platform; print(platform.platform())")
$(info ============================================)
$(info PLATFORM_VERSION_CODENAME=$(PLATFORM_VERSION_CODENAME))
$(info PLATFORM_VERSION=$(PLATFORM_VERSION))
$(info TARGET_PRODUCT=$(TARGET_PRODUCT))
$(info TARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT))
$(info TARGET_BUILD_TYPE=$(TARGET_BUILD_TYPE))
$(info TARGET_BUILD_APPS=$(TARGET_BUILD_APPS))
$(info TARGET_ARCH=$(TARGET_ARCH))
$(info TARGET_ARCH_VARIANT=$(TARGET_ARCH_VARIANT))
$(info TARGET_CPU_VARIANT=$(TARGET_CPU_VARIANT))
$(info TARGET_2ND_ARCH=$(TARGET_2ND_ARCH))
$(info TARGET_2ND_ARCH_VARIANT=$(TARGET_2ND_ARCH_VARIANT))
$(info TARGET_2ND_CPU_VARIANT=$(TARGET_2ND_CPU_VARIANT))
$(info HOST_ARCH=$(HOST_ARCH))
$(info HOST_OS=$(HOST_OS))
$(info HOST_OS_EXTRA=$(HOST_OS_EXTRA))
$(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE))
$(info BUILD_ID=$(BUILD_ID))
$(info OUT_DIR=$(OUT_DIR))
$(info ============================================)
endif
小結:
大多數的變量配置都是在config.mk中設置的,尤其是其包含的envsetup.mk文件。所以,就在config.mk的最後包含dumpvar.mk文件,該文件執行@echo $(DUMPVAR_VALUE)輸出$1變量值。
Examples:
1、get_abs_build_var ANDROID_GCC_PREBUILTS
#####################
# file:envsetup.mk #
#####################
34 # ---------------------------------------------------------------
35 # Set up configuration for host machine. We don't do cross-
36 # compiles except for arm/mips, so the HOST is whatever we are
37 # running on
38
39 UNAME := $(shell uname -sm)
40
41 # HOST_OS
42 ifneq (,$(findstring Linux,$(UNAME)))
43 <u><strong>HOST_OS</strong></u> := linux
44 endif
45 ifneq (,$(findstring Darwin,$(UNAME)))
46 HOST_OS := darwin
47 endif
48 ifneq (,$(findstring Macintosh,$(UNAME)))
49 HOST_OS := darwin
50 endif
51 ifneq (,$(findstring CYGWIN,$(UNAME)))
52 HOST_OS := windows
53 endif
108 # We don't want to move all the prebuilt host tools to a $(HOST_OS)-x86_64 dir.
109 HOST_PREBUILT_ARCH := x86
110 # This is the standard way to name a directory containing prebuilt host
111 # objects. E.g., prebuilt/$(HOST_PREBUILT_TAG)/cc
112 ifeq ($(HOST_OS),windows)
113 HOST_PREBUILT_TAG := windows
114 else
115 HOST_PREBUILT_TAG := $(HOST_OS)-$(HOST_PREBUILT_ARCH)
116 endif
##############
# dumpvar.mk #
##############
./dumpvar.mk:ANDROID_GCC_PREBUILTS := prebuilts/gcc/$(HOST_PREBUILT_TAG)
2、get_abs_build_var PRODUCT_OUT
#####################
# file:envsetup.mk #
#####################
192 # the target build type defaults to release
193 ifneq ($(TARGET_BUILD_TYPE),debug)
194 TARGET_BUILD_TYPE := release
195 endif
196
197 # ---------------------------------------------------------------
198 # figure out the output directories
199
200 ifeq (,$(strip $(OUT_DIR)))
201 ifeq (,$(strip $(OUT_DIR_COMMON_BASE)))
202 OUT_DIR := $(TOPDIR)out
203 else
204 OUT_DIR := $(OUT_DIR_COMMON_BASE)/$(notdir $(PWD))
205 endif
206 endif207
208 DEBUG_OUT_DIR := $(OUT_DIR)/debug
209
210 # Move the host or target under the debug/ directory
211 # if necessary.
212 TARGET_OUT_ROOT_release := $(OUT_DIR)/target
213 TARGET_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/target
214 TARGET_OUT_ROOT := $(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE))
227 TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/product
232 PRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)
#####################
# product_config.mk #
#####################
./product_config.mk:TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
# 該變量的分析將獨立寫一篇文章介紹。
3、get_abs_build_var HOST_OUT
#####################
# file: envsetup.mk #
#####################
1 # Variables we check:
2 # HOST_BUILD_TYPE = { release debug }
3 # TARGET_BUILD_TYPE = { release debug }
4 # and we output a bunch of variables, see the case statement at
5 # the bottom for the full list
6 # OUT_DIR is also set to "out" if it's not already set.
7 # this allows you to set it to somewhere else if you like
97 # the host build defaults to release, and it must be release or debug
98 ifeq ($(HOST_BUILD_TYPE),)
99 HOST_BUILD_TYPE := release
100 endif
101
102 ifneq ($(HOST_BUILD_TYPE),release)
103 ifneq ($(HOST_BUILD_TYPE),debug)
104 $(error HOST_BUILD_TYPE must be either release or debug, not '$(HOST_BUILD_TYPE)')
105 endif
106 endif
216 HOST_OUT_ROOT_release := $(OUT_DIR)/host # OUT_DIR 見2的分析。
217 HOST_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/host # DEBUG_OUT_DIR 見2的分析。
220 # We want to avoid two host bin directories in multilib build.
221 HOST_OUT_release := $(HOST_OUT_ROOT_release)/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
# HOST_OS 見 1 的分析。
222 HOST_OUT_debug := $(HOST_OUT_ROOT_debug)/$(HOST_OS)-$(HOST_PREBUILT_ARCH)
# HOST_PREBUILT_ARCH 見 1 的分析。
223 HOST_OUT := $(HOST_OUT_$(HOST_BUILD_TYPE))
4、get_build_var TARGET_DEVICE
#####################
# product_config.mk #
#####################
./product_config.mk:TARGET_DEVICE := $(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_DEVICE)
# 該變量的分析將獨立寫一篇文章介紹。
5、get_build_var TARGET_GCC_VERSION
TARGET_GCC_VERSION是在combo/TARGET_linux-$(TARGET_ARCH).mk文件中賦的值。
而TARGET_linux-$(TARGET_ARCH).mk文件是有config.mk -> combo/select.mk文件選擇性包含進來的。
6、get_build_var 2ND_TARGET_GCC_VERSION
./core/envsetup.mk:254:HOST_2ND_ARCH_VAR_PREFIX := 2ND_
./core/envsetup.mk:297:TARGET_2ND_ARCH_VAR_PREFIX := $(HOST_2ND_ARCH_VAR_PREFIX)
./core/config.mk:156:include $(BUILD_SYSTEM)/envsetup.mk
./core/config.mk:230:combo_2nd_arch_prefix :=
./core/config.mk:236:combo_2nd_arch_prefix := $(HOST_2ND_ARCH_VAR_PREFIX)
./core/config.mk:244:combo_2nd_arch_prefix :=
./core/config.mk:250:combo_2nd_arch_prefix := $(TARGET_2ND_ARCH_VAR_PREFIX)
$(combo_2nd_arch_prefix)TARGET_GCC_VERSION的賦值是在combo/TARGET_linux-$(TARGET_ARCH).mk 文件中賦的值。
7、get_build_var TARGET_ARCH
TARGET_ARCH是在BoardConfig.mk文件中賦的值。
BoardConfig.mk文件是由config.mk -> envsetup.mk中的$(board_config_mk)變量包含進來的。
8、get_build_var ANDROID_BUILD_PATHS
./core/envsetup.mk:238:HOST_OUT_EXECUTABLES := $(HOST_OUT)/bin
# HOST_OUT 見 3 的分析。
##############
# dumpvar.mk #
##############
ifneq ($(filter /%,$(HOST_OUT_EXECUTABLES)),)
ABP:=$(HOST_OUT_EXECUTABLES)
else
ABP:=$(PWD)/$(HOST_OUT_EXECUTABLES)
endif
ANDROID_BUILD_PATHS := $(ABP)
9、get_build_var report_config
在dumpvar.mk中,目標是report_config的代碼流程如下:
ifneq ($(dumpvar_goals),report_config)
PRINT_BUILD_CONFIG:=
endif
endif # CALLED_FROM_SETUP
ifneq ($(PRINT_BUILD_CONFIG),)
HOST_OS_EXTRA:=$(shell python -c "import platform; print(platform.platform())")
$(info ============================================)
$(info PLATFORM_VERSION_CODENAME=$(PLATFORM_VERSION_CODENAME))
# ./core/version_defaults.mk:62: PLATFORM_VERSION_CODENAME := REL
$(info PLATFORM_VERSION=$(PLATFORM_VERSION))
# ./core/version_defaults.mk:44: PLATFORM_VERSION := 5.1
$(info TARGET_PRODUCT=$(TARGET_PRODUCT))
# 是lunch時選擇的<product_name>
# ./envsetup.sh: export TARGET_PRODUCT=$product
$(info TARGET_BUILD_VARIANT=$(TARGET_BUILD_VARIANT))
# 是lunch時選擇的<product_variant>
# ./envsetup.sh: export TARGET_BUILD_VARIANT=$variant
$(info TARGET_BUILD_TYPE=$(TARGET_BUILD_TYPE))
# 是lunch時默認指定的,release
# ./envsetup.sh: export TARGET_BUILD_TYPE=release
$(info TARGET_BUILD_APPS=$(TARGET_BUILD_APPS))
# 是lunch時默認指定的,空值
# ./envsetup.sh: export TARGET_BUILD_APPS=
$(info TARGET_ARCH=$(TARGET_ARCH)) # TARGET_ARCH 見 7 的分析。
$(info TARGET_ARCH_VARIANT=$(TARGET_ARCH_VARIANT))
# 是在$(board_config_mk)即 BoardConfig.mk文件中賦的值。
$(info TARGET_CPU_VARIANT=$(TARGET_CPU_VARIANT))
# 是在$(board_config_mk)即 BoardConfig.mk文件中賦的值。
$(info TARGET_2ND_ARCH=$(TARGET_2ND_ARCH))
# 是在$(board_config_mk)即 BoardConfig.mk文件中賦的值。
$(info TARGET_2ND_ARCH_VARIANT=$(TARGET_2ND_ARCH_VARIANT))
# 是在$(board_config_mk)即 BoardConfig.mk文件中賦的值。
$(info TARGET_2ND_CPU_VARIANT=$(TARGET_2ND_CPU_VARIANT))
# 是在$(board_config_mk)即 BoardConfig.mk文件中賦的值。
$(info HOST_ARCH=$(HOST_ARCH))
# ./core/envsetup.mk:79: HOST_ARCH := x86_64
$(info HOST_OS=$(HOST_OS)) # HOST_OS 見 1 的分析。
$(info HOST_OS_EXTRA=$(HOST_OS_EXTRA)) # ifneq 的第一行。
$(info HOST_BUILD_TYPE=$(HOST_BUILD_TYPE)) # HOST_BUILD_TYPE 見 3 的分析。
$(info BUILD_ID=$(BUILD_ID))
# ./core/build_id.mk:21:export BUILD_ID=LMY47D
$(info OUT_DIR=$(OUT_DIR)) # OUT_DIR 見 2 的分析。
$(info ============================================)
endif