./scripts/Makefile.clean 文件分析

patsubst函数
$(clean-dirs):
    make -f ./scripts/Makefile.clean obj=$(patsubst _clean_%,%,$@)

$(clean-dirs) = $(addprefix _clean_, $(u-boot-alldirs))
$(libs-)$(u-boot-dirs)
$(libs-y)tools
dts/drivers/net/fm/lib/ fs/disk/ drivers/ drivers/dma/
drivers/ddr/fsl/drivers/ddr/fsl/drivers/gpio/ drivers/i2c/drivers/net/drivers/net/phy/drivers/power/
drivers/ddr/altera/drivers/usb/gadget/drivers/power/domain/drivers/power/fuel_gauge/drivers/power/mfd/drivers/power/pmic/drivers/power/battery/
drivers/usb/gadget/drivers/usb/gadget/udc/drivers/power/regulator/drivers/spi/drivers/serial/drivers/usb/cdns3/drivers/usb/dwc3/examples
api/test/drivers/usb/common/drivers/usb/emul/drivers/usb/eth/drivers/usb/host/drivers/usb/mtu3/
test/env/ test/optee/ drivers/usb/musb/drivers/usb/musb-new/drivers/usb/phy/drivers/usb/ulpi/cmd/
test/overlay/common/env/net/
# scripts/Makefile.clean
8	PHONY := __clean
9	__clean:
......
74	__clean: $(subdir-ymn)
75	ifneq ($(strip $(__clean-files)),)
76		+$(call cmd,clean)
77	endif
78	ifneq ($(strip $(__clean-dirs)),)
79		+$(call cmd,cleandir)
80	endif
81		@:
82
91	PHONY += $(subdir-ymn)
92	$(subdir-ymn):
93		$(Q)$(MAKE) $(clean)=$@
94
95	.PHONY: $(PHONY)

使用make -f命令来直接调用和执行scripts/Makefile.clean,伪目标为__clean$(subdir-ymn),由于输入命令没有指定创建的目标,所以默认第一个目标__clean为终极目标,只需创建终极目标__clean即可。由上可知,依赖关系如下:
在这里插入图片描述

  1. 创建__clean,见《2. 创建 __clean》,删除符合 《__clean-files 变量表格》 《clean-dirs 列表》中定义的指定目录,打印和执行;
    1.1 创建$(subdir-ymn),见《1. 创建 $(subdir-ymn)》,查询 《clean-dirs列表》中的目录及指定子目录中包含Makefile的目录,打印和执行;


最终:

  1. 打印和执行 《clean-dirs 列表》中的目录及其指定子目录下所有包含Makefile的路径名。【子目录名在$(obj-y) $(obj-m) $(obj-) $(subdir-y) $(subdir-m) $(subdir-) $(subdir-ym)这些变量中定义,这些变量在列出目录中的Makefile中定义】
  2. 打印和执行,删除步骤1列出的目录下所有符合下列变量列出的文件或目录。【这些变量在列出的目录或其子目录下的Makefile中定义】
$(extra-y) $(extra-m) $(extra-)
$(always) $(targets) $(clean-files)
$(hostprogs-y) $(hostprogs-m) $(hostprogs-)
$(hostlibs-y) $(hostlibs-m) $(hostlibs-)
$(hostcxxlibs-y) $(hostcxxlibs-m) $(clean-dirs)

1. 创建 $(subdir-ymn)

# scripts/Makefile.clean
6	src := $(obj)
14	kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
15	include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
......
20	__subdir-y	:= $(patsubst %/,%,$(filter %/, $(obj-y)))
21	subdir-y	+= $(__subdir-y)
22	__subdir-m	:= $(patsubst %/,%,$(filter %/, $(obj-m)))
23	subdir-m	+= $(__subdir-m)
24	__subdir-	:= $(patsubst %/,%,$(filter %/, $(obj-)))
25	subdir-		+= $(__subdir-)
29	subdir-ym	:= $(sort $(subdir-y) $(subdir-m))
30	subdir-ymn  := $(sort $(subdir-ym) $(subdir-))
34	subdir-ymn	:= $(addprefix $(obj)/,$(subdir-ymn))
......
38	subdir-ymn	:= $(foreach f, $(subdir-ymn), $(if $(wildcard $(srctree)/$f/Makefile),$f))
92	$(subdir-ymn):
93		$(Q)$(MAKE) $(clean)=$@
  1. 6行:$(obj)在命令行make -f ./scripts/Makefile.clean obj=$(patsubst _clean_%,%,$@)中被定义,所以:
    src = $(clean-dirs)列表中的所有值
  2. 14行:由 <6行> 可知,src = $(clean-dirs)列表中的所有值,所以:
    如果$(clean-dirs)列表中的值 = /% kbuild-dir = $(clean-dirs)列表中的原值
    如果$(clean-dirs)列表中的值 != /% kbuild-dir =./ $(clean-dirs)列表中的原值
  3. 15行:判断 <14行> 中kbuild-dir【即$(clean-dirs)列表中的所有值 】下是否存在Kbuild文件,
    如果存在,  引用该目录下的 Kbuild
    如果不存在 引用该目录下的 Makefile
  4. 20-30行:subdir-ymn = $(obj-y) $(obj-m) $(obj-) $(subdir-y) $(subdir-m) $(subdir-) $(subdir-ym)【这些变量在第15行中所引用的文件中定义】,即查询当前目录下的子目录。sort函数、patsubst函数、filter函数
  5. 34行:将查询到的子目录名加上绝对路径。
  6. 38行:轮询查找所有当前目录和当前目录下的子目录中存在Makefile文件的路径名。foreach函数、wildcard函数


目标$(subdir-ymn)没有依赖,所以只需执行目标的创建语句即可。


最终:打印和执行:make -f ./scripts/Makefile.clean obj=所有存在Makefile文件的目录名
层层查询 《$(clean-dirs)列表》中列出的目录及其子目录中包含Makefile文件的目录名。【子目录名在$(obj-y) $(obj-m) $(obj-) $(subdir-y) $(subdir-m) $(subdir-) $(subdir-ym)这些变量中定义,这些变量在主目录中的Makefile中定义】

2. 创建 __clean

编译前后相应目录下文件对比如下:

目录编译后编译前
dtsdts/dt.dtb
dts/dt.dtb.S
不存在
dts/…/arch/arm/dtsdts/…/arch/arm/dts/bcm2837-rpi-3-b.dtb
dts/…/arch/arm/dts/bcm2835-rpi-b-plus.dtb
dts/…/arch/arm/dts/bcm2835-rpi-a-plus.dtb
dts/…/arch/arm/dts/bcm2835-rpi-b.dtb
dts/…/arch/arm/dts/bcm2835-rpi-a.dtb
dts/…/arch/arm/dts/bcm2835-rpi-cm1-io1.dtb
dts/…/arch/arm/dts/bcm2837-rpi-3-b-plus.dtb
dts/…/arch/arm/dts/bcm2835-rpi-zero-w.dtb
dts/…/arch/arm/dts/bcm2835-rpi-b-rev2.dtb
dts/…/arch/arm/dts/bcm2836-rpi-2-b.dtb
dts/…/arch/arm/dts/bcm2837-rpi-3-a-plus.dtb
dts/…/arch/arm/dts/bcm2837-rpi-cm3-io3.dtb
dts/…/arch/arm/dts/bcm2835-rpi-zero.dtb
不存在
toolstools/mkenvimage
tools/dumpimage
tools/mkimage
tools/proftool
tools/fdtgrep
tools/spl_size_limit
tools/mkenvimage
tools/dumpimage
tools/mkimage
tools/proftool
tools/fdtgrep
tools/spl_size_limit
tools/gen_eth_addr
tools/gen_ethaddr_crc
tools/img2srec
不存在
scripts/basicscripts/basic/fixdep
scripts/basic/fixdep
不存在
scripts/dtcscripts/dtc/dtc
scripts/dtc/dtc
不存在
scripts/kconfigscripts/kconfig/conf不存在
其他不存在不存在
__clean-files 变量表格
$(extra-y) $(extra-m) $(extra-)
$(always) $(targets) $(clean-files)
$(hostprogs-y) $(hostprogs-m) $(hostprogs-)
$(hostlibs-y) $(hostlibs-m) $(hostlibs-)
$(hostcxxlibs-y) $(hostcxxlibs-m)

# scripts/Makefile.clean
6	src := $(obj)
14	kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
15	include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
......
44	__clean-files	:= 	$(extra-y) $(extra-m) $(extra-)       \
45			   			$(always) $(targets) $(clean-files)   \
46			  			$(hostprogs-y) $(hostprogs-m) $(hostprogs-) \
47			   			$(hostlibs-y) $(hostlibs-m) $(hostlibs-) \
48			   			$(hostcxxlibs-y) $(hostcxxlibs-m)
50	__clean-files   := 	$(filter-out $(no-clean-files), $(__clean-files))
56	__clean-files   := 	$(wildcard                                               \
57			   			$(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
58			   			$(filter $(objtree)/%, $(__clean-files)))
62	__clean-dirs    := 	$(wildcard                                               \
63			   			$(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs)))    \
64			   			$(filter $(objtree)/%, $(clean-dirs)))
......
69  cmd_clean    = rm -f $(__clean-files)
71  cmd_cleandir = rm -rf $(__clean-dirs)
......
74	__clean: $(subdir-ymn)
75	ifneq ($(strip $(__clean-files)),)
76		+$(call cmd,clean)
77	endif
78	ifneq ($(strip $(__clean-dirs)),)
79		+$(call cmd,cleandir)
80	endif
81		@:

由上面 《1. 生成目标 $(subdir-ymn)》可知,目标__clean的依赖已经生成,接下来执行目标__clean的生成语句。
wildcard函数、addprefix函数、filter-out函数、filter函数、strip函数、call函数、cmd函数

  1. 6-15行:由《1. 创建 $(subdir-ymn)》可知,这里会引用相应目录下的KbuildMakefile
  2. 44行: 《__clean-files 变量表格》 中的变量都在 <6-15行> 引用的KbuildMakefile文件中定义。
  3. 50行:$(no-clean-files)为空,所有这里是将第44行中变量为空的部分过滤掉。
  4. 56行:查找 《__clean-files 变量表格》 中不符合./%模式的单词,将其添加$(obj)/前缀,并查找符合./%模式的单词,最后通过wildcard函数去相应目录下匹配指定模式的所有文件名列表,如果相应目录下没有指定文件名则匹配失败返回空字符串。【即列出当前目录下符合 《__clean-files 变量表格》 定义的指定文件,不存在不列出】
  5. 62行:列出$(clean-dirs) <在15行引用的Kbuild或Makefile文件中定义>中定义的指定目录,不存在不列出。
  6. 75-77行:删除并回显 <56行> 中列出的文件
  7. 78-80行:删除并回显 <62行> 中列出的目录
  8. 81行:@表示不显示源命令,:是bash的内建命令,效果就是就是什么都不做, 并且总是返回状态0,所以总体来说 @: 就是什么都不做,如果后面有参数,等同于注释掉。


最终:

  1. 删除当前目录下符合 《__clean-files 变量表格》 定义的指定文件。
  2. 打印和执行,删除 《clean-dirs 列表》中定义的指定目录<在15行引用的KbuildMakefile中定义>。
  • 25
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值