文章目錄
- 目標 $(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,所以總體來說@:
就是什么都不做,如果后面有參數,等同于注釋掉。