./scripts/Makefile.clean 文件分析

news2024/12/26 11:58:51

文章目录

  • 目标 $(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_tools
api
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行引用,这些变量都定义相应目录下的KbuildMakefile文件中。
第50行,$(no-clean-files)为空,所有这里是将第44行中变量为空的部分过滤掉。
第56行,查找$(__clean-files) 中不符合./%模式的单词,并将其添加$(obj)/前缀,和查找$(__clean-files) 中符合./%模式的单词,最后通过wildcard函数去相应目录下匹配指定模式的所有文件名列表,如果相应目录下没有指定文件名则匹配失败返回空字符串。编译前后相应目录下文件对比如下:wildcard函数、addprefix函数、filter-out函数、filter函数

目录编译后编译前
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)一般为空,只有编译后的情况下(如上表中所示),部分不为空。不为空时,执行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/Makefilescripts/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,所以总体来说 @: 就是什么都不做,如果后面有参数,等同于注释掉。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1684648.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【spring】@CrossOrigin注解学习

CrossOrigin介绍 CrossOrigin 是 Spring Framework 中的一个注解,用于处理跨域资源共享(CORS)问题。CORS 是一种机制,它使用额外的 HTTP 头来告诉浏览器,让运行在一个 origin (domain) 上的Web应用被准许访问来自不同…

linux 安装redis 并设置开机启动

个人实测 流程 1、第一步 先下载redis ** redis地址 https://download.redis.io/releases/选择你想要的版本 我下载的是 如下图 2、第二步:把下载的包放到linux里面 我用的是 XSHELL 和XFTP 放到/usr/local/java路径下 你可以随便放 3、第三步: ** 执行 以下命令 进行解压 t…

10最佳iPhone数据恢复软件评论

您还在寻找最好的iPhone数据恢复软件吗? 似乎我们在iPhone上放置了越来越多与日常生活和工作有关的重要事情。照片可以保持珍贵的时刻,联系人可以保持联系,录音,备忘录和日历可以作为提醒,视频和歌曲可以娱乐&#xf…

“现代汽车中国前瞻软件赛杯” 牛客周赛 Round 43

A. 小红平分糖果&#xff08;签到&#xff09; // Problem: 小红平分糖果 // Contest: NowCoder // URL: https://ac.nowcoder.com/acm/contest/82394/A // Memory Limit: 524288 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)#include<b…

史上最快AI大模型炸场!人工智能将如何影响你的未来?

一觉醒来&#xff0c;每秒能输出500个tokens的大模型Groq刷屏全网。 堪称是“世界上速度最快的LLM”&#xff01; 相比之下&#xff0c;ChatGPT-3.5每秒生成速度仅为40个tokens(token&#xff0c;中文名称为令牌&#xff0c;是一种特殊的计算机术语&#xff0c;常用于网络通讯…

倪海夏的思维逻辑总结

1《天纪》是自然法则&#xff0c;自然法则是个《真理》&#xff0c; 《真理》不需要再证实&#xff0c;《真理》没有二元对立。 《真理》没有例外。 2研究任何学问&#xff08;事物&#xff09;&#xff0c;批判去看&#xff0c;假设--验证--结果。 以果决其行&#xff0…

[IMX6ULL驱动开发]-Linux对中断的处理(一)

目录 中断概念的引入 ARM架构中断的流程 异常向量表 Linux系统对中断的处理 ARM对程序和中断的处理 Linux进程中断处理 中断概念的引入 如何理解中断&#xff0c;我们可以进行如下抽象。把CPU看做一个母亲&#xff0c;当它正在执行任务的时候&#xff0c;可以看为是一个母…

Modbus-RTU/TCP规约 | 报文解析 | 组织报文与解析报文(C++)

文章目录 一、MODBUS规约1.MODBUS-RTU规约2.MODBUS-TCP规约 二、报文解析1.MODBUS-RTU报文帧解析2.MODBUS-TCP报文帧解析 三、C代码实现组织报文与解析报文 一、MODBUS规约 Modbus规约是一种广泛使用的串行通信协议&#xff08;应用层报文传输协议&#xff09;&#xff0c;用于…

C++质数的那些事(判断指数、区间筛质数、互质等等)

质数的定义&#xff1a;若一个正整数除了1和它自身之外不能被任何自然数整除&#xff0c;则该数称为质数&#xff0c;也叫素数。否则为合数。 质数的性质&#xff1a;质数的分布较为稀疏&#xff0c;对于一个足够大的数S&#xff0c;不超过S的质数大约有个&#xff0c;也就是说…

视频安防监控EasyCVR视频汇聚管理平台视频播放花屏的原因分析及处理

智慧安防监控EasyCVR视频管理平台能在复杂的网络环境中&#xff0c;将前端设备统一集中接入与汇聚管理。国标GB28181协议视频监控/视频汇聚EasyCVR平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、…

基于SpringBoot和Hutool工具包实现的验证码案例

目录 验证码案例 1. 需求 2. 准备工作 3. 约定前后端交互接口 需求分析 接口定义 4. Hutool 工具介绍 5. 实现验证码 后端代码 前端代码 6. 运行测试 验证码案例 随着安全性的要求越来越高&#xff0c;目前项目中很多都会使用验证码&#xff0c;只要涉及到登录&…

【C语言】VS编译器的scanf

我们在写代码的时候通常需要用到输入函数&#xff1a;scanf&#xff0c;但在vs编译环境下却必须写为&#xff1a;scanf_s&#xff0c;这是为什么呢&#xff1f;这里就是vs规定的了&#xff0c;VS认为这样写更安全&#xff0c;但如果我们非要写成scanf形式也是有办法的。 # 看我…

hls.js实现分片播放视频

前言&#xff1a;hls.js官网&#xff1a;hls.js - npm 一、demo——在HTML中使用 <audio id"audio" controls></audio><script src"https://cdn.jsdelivr.net/npm/hls.jslatest"></script> <script>document.addEventList…

OTP8脚-全自动擦鞋机WTN6020-低成本语音方案

一&#xff0c;产品开发背景 首先&#xff0c;随着人们生活质量的提升&#xff0c;对鞋子的保养需求也日益增加。鞋子作为人们日常穿着的重要组成部分&#xff0c;其清洁度和外观状态直接影响到个人形象和舒适度。因此&#xff0c;一种能够自动清洁和擦亮鞋子的设备应运而生&am…

oracle中insert all的用法

1、简述 使用insert into语句进行表数据行的插入&#xff0c;但是oracle中有一个更好的实现方式&#xff1a;使用insert all语句。 insert all语句是oracle中用于批量写数据的 。insert all分又为 无判断条件插入有判断条件插入有判断条件插入分为 Insert all when... 子句 …

VMware 和 VirtualBox开机自启指定虚拟机详细教程

VMware上虚拟机随宿主机开机自启 1. 设置自动启动虚拟机 网上教程旧版的&#xff0c;界面和新版有所差异。17版本设置如下&#xff1a;VMware Workstation工作台 -> 文件 -> 配置自动启动虚拟机 -> 按顺序选择需要启动的虚拟机 VMWare17配置自动启动虚拟机提示&…

使用WindTerm通过公钥让其他同事登录linux服务器

1.其他同事电脑操作cmd输入 ssh-keygen,如果是第一次生成公钥&#xff0c;则直接一路回车确认就行 会生成在C:\Users\nideNAME\.ssh目录 公钥文件名为id_rsa.pub&#xff0c;私钥文件名为id_rsa。 2.你的电脑你已经连接上服务器了 在root下新建目录 root/.ssh/新建文件touck …

数据库小项目——叮叮移动业务大厅(三层架构+MySQL数据库)

源码已上传至资源 该项目主要使用技术为MySQL数据库&#xff0c;其中也包含了一些对于文件的写入和读取操作。项目结构采用三层架构&#xff0c;后端的业务逻辑清晰明了。 1.项目结构 项目采用控制台版&#xff0c;前端业务在java包下&#xff0c;每个业务单独成块。若想要GUI…

GD32F307+lwip+freeRTOS+DP83848 JPerf接收测速

1.原理图 2.代码 https://www.firebbs.cn/forum.php?modviewthread&tid26274&fromuid37393 //22_ENET 1&#xff09;注释掉tcp_client_init(); 2&#xff09;init_task中添加测速线程iperf_server_init() //main.c #include "gd32f30x.h" #include &quo…

自定义RedisTemplate序列化器

大纲 RedisSerializerFastJsonRedisSerializer自定义二进制序列化器总结代码 在《RedisTemplate保存二进制数据的方法》一文中&#xff0c;我们将Java对象通过《使用java.io库序列化Java对象》中介绍的方法转换为二进制数组&#xff0c;然后保存到Redis中。实际可以通过定制Red…