SuperIC社区_
标题: Android编译系统环境初始化过程分析(3) [打印本页]
作者: liuwei 时间: 2016-9-28 14:07
标题: Android编译系统环境初始化过程分析(3)
再回到build/core/config.mk文件中,它最后加载build/core/dumpvar.mk文件。加载build/core/dumpvar.mk文件是为了生成make目标,以便可以对这些目标进行操作。例如,在我们这个情景中,我们要执行的make目标是dumpvar-TARGET_DEVICE,因此在加载build/core/dumpvar.mk文件的过程中,就会生成dumpvar-TARGET_DEVICE目标。
文件build/core/dumpvar.mk的内容也比较多,这里我们只关注生成make目标相关的逻辑:
[plain] view plain copy


- ......
-
- # 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))))
- 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)
-
- endif # dumpvar_goals
-
- ......
我们在执行make命令时,指定的目示会经由MAKECMDGOALS变量传递到Makefile中,因此通过变量MAKECMDGOALS可以获得make目标。
上述代码的逻辑很简单,例如,在我们这个情景中,指定的make目标为dumpvar-TARGET_DEVICE,那么就会得到变量DUMPVAR_VALUE的值为$(TARGET_DEVICE)。TARGET_DEVICE的值在前面已经被设置为“generic”,因此变量DUMPVAR_VALUE的值就等于“generic”。此外,变量dumpvar_target的被设置为“dumpvar-TARGET_DEVICE”。最后我们就可以得到以下的make规则:
[plain] view plain copy


- .PHONY dumpvar-TARGET_DEVICE
- dumpvar-TARGET_DEVICE:
- @echo generic
至此,在build/envsetup.sh文件中定义的函数check_product就分析完成了。看完了之后,小伙伴们可能会问,前面不是说这个函数是用来检查用户输入的产品名称是否合法的吗?但是这里没看出哪一段代码给出了true或者false的答案啊。实际上,在前面分析的build/core/config.mk和build/core/product_config.mk等文件的加载过程中,如果发现输入的产品名称是非法的,也就是找不到相应的产品Makefile文件,那么就会通过调用error函数来产生一个错误,这时候函数check_product的返回值$?就会等于非0值。
接下来我们还要继续分析在build/envsetup.sh文件中定义的函数check_variant的实现,如下所示:
[plain] view plain copy


- VARIANT_CHOICES=(user userdebug eng)
-
- # check to see if the supplied variant is valid
- function check_variant()
- {
- for v in ${VARIANT_CHOICES[@]}
- do
- if [ "$v" = "$1" ]
- then
- return 0
- fi
- done
- return 1
- }
这个函数的实现就简单多了。合法的编译类型定义在数组VARIANT_CHOICES中,并且它只有三个值user、userdebug和eng。其中,user表示发布版本,userdebug表示带调试信息的发布版本,而eng表标工程机版本。
最后,我们再来分析在build/envsetup.sh文件中定义的函数printconfig的实现,如下所示:
[plain] view plain copy


- function printconfig()
- {
- T=$(gettop)
- if [ ! "$T" ]; then
- echo "Couldn't locate the top of the tree. Try setting TOP." >&2
- return
- fi
- get_build_var report_config
- }
对比我们前面对函数check_product的分析,就会发现函数printconfig的实现与这很相似,都是通过调用get_build_var来获得相关的信息,但是这里传递给函数get_build_var的参数为report_config。
我们跳过前面build/core/config.mk和build/core/envsetup.mk等文件对目标产品Makefile文件的加载,直接跳到build/core/dumpvar.mk文件来查看与report_config这个make目标相关的逻辑:
[plain] view plain copy


- ......
-
- dumpvar_goals := \
- $(strip $(patsubst dumpvar-%,%,$(filter dumpvar-%,$(MAKECMDGOALS))))
- .....
-
- ifneq ($(dumpvar_goals),report_config)
- PRINT_BUILD_CONFIG:=
- endif
-
- ......
-
- 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 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
变量PRINT_BUILD_CONFIG定义在文件build/core/envsetup.mk中,默认值设置为true。当make目标为report-config的时候,变量PRINT_BUILD_CONFIG的值就会被设置为空。因此,接下来就会打印一系列用来描述编译环境配置的变量的值,也就是我们执行lunch命令后看到的输出。注意,这些环境配置相关的变量量都是在加载build/core/config.mk和build/core/envsetup.mk文件的过程中设置的,就类似于前面我们分析的TARGET_DEVICE变量的值的设置过程。
至此,我们就分析完成Android编译系统环境的初始化过程了。从分析的过程可以知道,Android编译系统环境是由build/core/config.mk、build/core/envsetup.mk、build/core/product_config.mk、AndroidProducts.mk和BoardConfig.mk等文件来完成的。这些mk文件涉及到非常多的细节,而我们这里只提供了一个大体的骨架和脉络,希望能够起到抛砖引玉的作用。
欢迎光临 SuperIC社区_ (/) |
Powered by Discuz! X3.3 |