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