文章目录
- 目标 $(subdir-ymn)
- 目标__clean
$(clean-dirs):
make -f ./scripts/Makefile.clean obj=$(patsubst _clean_%,%,$@)
$(clean-dirs) $(patsubst _clean_%,%,$@) _clean_api
_clean_cmd
_clean_common
_clean_disk
_clean_drivers
_clean_drivers/ddr/altera
_clean_drivers/ddr/fsl
_clean_drivers/dma
_clean_drivers/gpio
_clean_drivers/i2c
_clean_drivers/net
_clean_drivers/net/fm
_clean_drivers/net/phy
_clean_drivers/power
_clean_drivers/power/battery
_clean_drivers/power/domain
_clean_drivers/power/fuel_gauge
_clean_drivers/power/mfd
_clean_drivers/power/pmic
_clean_drivers/power/regulator
_clean_drivers/serial
_clean_drivers/spi
_clean_drivers/usb/cdns3
_clean_drivers/usb/common
_clean_drivers/usb/dwc3
_clean_drivers/usb/emul
_clean_drivers/usb/eth
_clean_drivers/usb/gadget
_clean_drivers/usb/gadget/udc
_clean_drivers/usb/host
_clean_drivers/usb/mtu3
_clean_drivers/usb/musb
_clean_drivers/usb/musb-new
_clean_drivers/usb/phy
_clean_drivers/usb/ulpi
_clean_dts
_clean_env
_clean_examples
_clean_fs
_clean_lib
_clean_net
_clean_test
_clean_test/env
_clean_test/optee
_clean_test/overlay
_clean_toolsapi
cmd
common
disk
drivers
drivers/ddr/altera
drivers/ddr/fsl
drivers/dma
drivers/gpio
drivers/i2c
drivers/net
drivers/net/fm
drivers/net/phy
drivers/power
drivers/power/battery
drivers/power/domain
drivers/power/fuel_gauge
drivers/power/mfd
drivers/power/pmic
drivers/power/regulator
drivers/serial
drivers/spi
drivers/usb/cdns3
drivers/usb/common
drivers/usb/dwc3
drivers/usb/emul
drivers/usb/eth
drivers/usb/gadget
drivers/usb/gadget/udc
drivers/usb/host
drivers/usb/mtu3
drivers/usb/musb
drivers/usb/musb-new
drivers/usb/phy
drivers/usb/ulpi
dts
env
examples
fs
lib
net
test
test/env
test/optee
test/overlay
tools
01 # SPDX-License-Identifier: GPL-2.0
02 # ==========================================================================
03 # Cleaning up
04 # ==========================================================================
05
06 src := $(obj)
07
08 PHONY := __clean
09 __clean:
10
11 include scripts/Kbuild.include
12
13 # The filename Kbuild has precedence over Makefile
14 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
15 include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
16
17 # Figure out what we need to build from the various variables
18 # ==========================================================================
19
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-)
26
27 # Subdirectories we need to descend into
28
29 subdir-ym := $(sort $(subdir-y) $(subdir-m))
30 subdir-ymn := $(sort $(subdir-ym) $(subdir-))
31
32 # Add subdir path
33
34 subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
35
36 # Temporal work-around for U-Boot
37
38 subdir-ymn := $(foreach f, $(subdir-ymn), \
39 $(if $(wildcard $(srctree)/$f/Makefile),$f))
40
41 # build a list of files to remove, usually relative to the current
42 # directory
43
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)
49
50 __clean-files := $(filter-out $(no-clean-files), $(__clean-files))
51
52 # clean-files is given relative to the current directory, unless it
53 # starts with $(objtree)/ (which means "./", so do not add "./" unless
54 # you want to delete a file from the toplevel object directory).
55
56 __clean-files := $(wildcard \
57 $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) \
58 $(filter $(objtree)/%, $(__clean-files)))
59
60 # same as clean-files
61
62 __clean-dirs := $(wildcard \
63 $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) \
64 $(filter $(objtree)/%, $(clean-dirs)))
65
66 # ==========================================================================
67
68 quiet_cmd_clean = CLEAN $(obj)
69 cmd_clean = rm -f $(__clean-files)
70 quiet_cmd_cleandir = CLEAN $(__clean-dirs)
71 cmd_cleandir = rm -rf $(__clean-dirs)
72
73
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
83
84 # ===========================================================================
85 # Generic stuff
86 # ===========================================================================
87
88 # Descending
89 # ---------------------------------------------------------------------------
90
91 PHONY += $(subdir-ymn)
92 $(subdir-ymn):
93 $(Q)$(MAKE) $(clean)=$@
94
95 .PHONY: $(PHONY)
96
从上到下依次执行,伪目标
PHONY
在第8行和第91行可知,PHONY = __clean $(subdir-ymn)
,目标__clean
在74行定义了依赖和语句,$(subdir-ymn)
在92行定义了依赖和语句,所以从这两个目标的依赖和语句可知,优先执行目标$(subdir-ymn)
再执行目标__clean
。
目标 $(subdir-ymn)
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)=$@
30行:$(subdir-ym) 和 $(subdir-) 分析,在第20-29行定义:sort函数、patsubst函数、filter函数
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-) 26 27 # Subdirectories we need to descend into 28 29 subdir-ym := $(sort $(subdir-y) $(subdir-m))
$(obj-y)、$(obj-m)、$(obj-)
从何而来?06 src := $(obj) 14 kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src)) 15 include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile)
$(obj)具体的内容在最上面的表格中已经列举出来了,其中包含的单词既有符合
/%
模式的也有不符合的,第14行用来进行相应判断后赋值 kbuild-dir。例如:obj=api,kbuild-dir=./api
;obj=drivers/dma,kbuild-dir=drivers/dma
第15行,其实就是判断最上面表格列出的目录中是否存在Kbuild
文件,存在则引用此文件,不存在则引用目录中的Makefile
文件。
$(obj-y)、$(obj-m)、$(obj-)
三个变量定义在这相应目标的Kbuild
文件或Makefile
文件中,例如cmd目录下的Makefile:200 obj-$(CONFIG_CMD_SCP03) += scp03.o 202 obj-$(CONFIG_ARM) += arm/ 203 obj-$(CONFIG_RISCV) += riscv/ 204 obj-$(CONFIG_SANDBOX) += sandbox/ 205 obj-$(CONFIG_X86) += x86/
从
$(obj-y)、$(obj-m)、$(obj-)
中过滤掉所有不符合%/
模式的单词,保留所有符合此模式的单词,然后从所有符合%/
模式的单词中匹配到符合%/
的单词后,用%
进行替换 [也就是将最后的/
去除]。也就是从$(obj-y)、$(obj-m)、$(obj-)
中找到文件夹名。
结论:此行的subdir-ymn
其实就是Kbuild
文件或Makefile
文件中变量$(obj-y)、$(obj-m)、$(obj-)
所包含的文件夹名。34行:给第30行
$(subdir-ymn)
添加$(obj)/
前缀,$(obj)
内容在最上面表格中已经列出,addprefix函数
38行:判断$(obj)/$(subdir-ymn)
目录下是否存在 Makefile 文件,存在返回$(obj)/$(subdir-ymn)
,否则返回空。foreach函数、wildcard函数
92-93行:从引用的文件中过滤匹配$(obj-y)、$(obj-m)、$(obj-)
三个变量中的文件夹名,只保留文件夹名下有Makefile文件的文件名,也就是层层查询所有的Makefile文件所在的目录名。
最终回显:make -f ./scripts/Makefile.clean obj=所有存在Makefile文件的目录名
目标__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 @:
75行:__clean-files 定义如下,strip函数
44 __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) 50 __clean-files := $(filter-out $(no-clean-files), $(__clean-files)) 56 __clean-files := $(wildcard $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(__clean-files))) $(filter $(objtree)/%, $(__clean-files)))
第44行,根据第15行引用,这些变量都定义相应目录下的
Kbuild
或Makefile
文件中。
第50行,$(no-clean-files)
为空,所有这里是将第44行中变量为空的部分过滤掉。
第56行,查找$(__clean-files)
中不符合./%
模式的单词,并将其添加$(obj)/
前缀,和查找$(__clean-files)
中符合./%
模式的单词,最后通过wildcard函数
去相应目录下匹配指定模式的所有文件名列表,如果相应目录下没有指定文件名则匹配失败返回空字符串。编译前后相应目录下文件对比如下:wildcard函数、addprefix函数、filter-out函数、filter函数
目录 编译后 编译前 dts dts/dt.dtb
dts/dt.dtb.S不存在 dts/…/arch/arm/dts dts/…/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不存在 tools tools/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/basic scripts/basic/fixdep
scripts/basic/fixdep不存在 scripts/dtc scripts/dtc/dtc
scripts/dtc/dtc不存在 scripts/kconfig scripts/kconfig/conf 不存在 其他 不存在 不存在 所以此行中
$(__clean-files)
一般为空,只有编译后的情况下(如上表中所示),部分不为空。不为空时,执行cmd_clean
函数:69 cmd_clean = rm -f $(__clean-files)
78行:$(__clean-dirs) 定义如下:
62 __clean-dirs := $(wildcard $(addprefix $(obj)/, $(filter-out $(objtree)/%, $(clean-dirs))) $(filter $(objtree)/%, $(clean-dirs)))
其中
$(clean-dirs)
定义在第15行引用的Kbuild
或者Makefile
文件中,通过打印测试发现,只有tools/Makefile
和scripts/kconfig/Makefile
文件中有定义clean-dirs
,分别为: clean-dirs += lib common 和 clean-dirs += tests/.cache,其他的都未定义,$(clean-dirs)
为空。
所以此行中$(__clean-dirs)
一般为空,只有tools 和 scripts/kconfig 不为空。不为空时,执行cmd_cleandir
函数:71 cmd_cleandir = rm -rf $(__clean-dirs)
81行:命令前加
@
表示不显示源命令,:
是bash的内建命令,效果就是就是什么都不做, 并且总是返回状态0,所以总体来说@:
就是什么都不做,如果后面有参数,等同于注释掉。