Building System之 get_abs_build_var() && get_build_var()


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




發佈了65 篇原創文章 · 獲贊 58 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章