一 UBOOT编译--- make xxx_deconfig过程详解( 三 )

2.2 $(echo-cmd) $(cmd_ $ (1))等价于$(echo-cmd) $(cmd_host-csingle)
echo-cmd = $(if $( $(quiet)cmd_$(1)),echo '$(call escsq, $( $(quiet)cmd_ $(1))) $(echo-why)';)quiet=quiet_ , 在顶层Makefile分析过(当然如果你想看到更详细的打印 , 您可以通过传入V值,来改变) ,  $(cmd_host-csingle)上面分析过,存在,所以:
echo-cmd = echo '$(call escsq,$(cmd_host-csingle))$(echo-why)';在scripts/Kbuild.include中:
# Escape single quote for use in echo statementsescsq = $(subst $(squote),'\$(squote)',$1)ifeq ($(KBUILD_VERBOSE),2)why =\$(if $(filter $@, $(PHONY)),- due to target is PHONY,\$(if $(wildcard $@),\$(if $(strip $(any-prereq)),- due to: $(any-prereq),\$(if $(arg-check),\$(if $(cmd_$@),- due to command line change,\$(if $(filter $@, $(targets)),\- due to missing .cmd file,\- due to $(notdir $@) not in $$(targets)\)\)\)\),\- due to target missing\)\)echo-why = $(call escsq, $(strip $(why)))endifKBUILD_VERBOSE一般我们会采用默认值0(需要调试编译除外),所以 echo-why 为空 。
quiet_cmd_host-csingle= HOSTCC$@ //用来打印cmd_host-csingle ='$(HOSTCC) $(hostc_flags) -o $@ $<$(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))'$(HOSTCC)为cc , 此处不再深入解释,hostc_flags在Makefile.host中定义:
###### Handle options to gcc. Support building with separate output directory_hostc_flags= $(HOSTCFLAGS)$(HOST_EXTRACFLAGS)\$(HOSTCFLAGS_$(basetarget).o) //-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \$(HOSTCXXFLAGS_$(basetarget).o)ifeq ($(KBUILD_SRC),) //KBUILD_SRC在make命令行定义,此处未定义__hostc_flags = $(_hostc_flags)__hostcxx_flags = $(_hostcxx_flags)else__hostc_flags = -I$(obj) $(call flags,_hostc_flags)__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags)endifhostc_flags= -Wp,-MD,$(depfile) $(__hostc_flags)在scripts/Kbuild.include中:
comma:= ,dot-target = $(dir $@).$(notdir $@)//scripts/basic/.fixdepdepfile = $(subst $(comma),_,$(dot-target).d)//scripts/basic/.fixdep.dhostc_flags=-Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer

综上cmd_host-csingle = cc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/fixdep scripts/basic/fixdep.c
所以echo-cmd 的作用是打印quiet_cmd_host-csingle(HOSTCC $ @ )或者cmd_host-csingle(根据顶层MakefileV值决定),$ (cmd_$(1))即为执行cmd_host-csingle生成fixdep同时生成fixdep的依赖文件.fixdep.d
(2.3) scripts/basic/fixdep $(depfile) $@ ’ $(make-cmd)’ > $(dot-target).tmp 等价于:scripts/basic/fixdep scripts/basic/.fixdep.d scripts/basic/fixdep ‘cc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/fixdep scripts/basic/fixdep.c’ > scripts/basic/.fixdep.tmp
(2.4) rm -f $(depfile) 删除scripts/basic/.fixdep.d
(2.5) mv -f $(dot-target).tmp $(dot-target).cmd) 将scripts/basic/.fixdep.tmp重命名为scripts/basic/.fixdep.cmd
总结:生成scripts/basic/fixdep的过程中会先打印cc -Wp,-MD,scripts/basic/.fixdep.d -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -o scripts/basic/fixdep scripts/basic/fixdep.c同时执行该语句生成fixdep,再用fixdep生成.fixdep.cmd
4.2 依赖 outputmakefile# 顶层Makefile# outputmakefile generates a Makefile in the output directory, if using a# separate output directory. This allows convenient use of make in the# output directory.outputmakefile:ifneq ($(KBUILD_SRC),) $(Q)ln -fsn $(srctree) source $(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \$(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)endif上面批注已经说的很清楚了,outputmakefile 在输出目录中生成一个 Makefile,如果使用单独的输出目录 。这允许在输出目录中方便地使用 make 。当KBUILD_SRC不为空时,才会编译到这里 。
4.3 依赖 FORCE# 顶层MakefilePHONY += FORCEFORCE:实际上它是一个伪目标,从上面看到,FORCE 既没有依赖的规则,其底下也没有可执行的命令 。如果一个规则没有命令或者依赖,而且它的目标不是一个存在的文件名,在执行此规则时 , 目标总会被认为是最新的 。也就是说,这个规则一旦被执行 , make 就认为它所表示的目标已经被更新过 。当将这样的目标(FORCE)作为一个规则的依赖时(如上),由于依赖总被认为是被更新过的,所以作为依赖所在的规则定义的命令总会被执行 。
4.4 规则 $ (Q)$(MAKE) $(build)=scripts/kconfig $@等价于:make -f $(srctree)/scripts/Makefile.build obj=scripts/kconfig myimx8mmek240-8mm-2g_defconfig
在scripts/kconfig/Makefile中(至于为什么会引用scripts/kconfig/Makefile , 参见4.1小节)

推荐阅读