Using Makefile to clean subdirectories
是否可以从父目录执行make clean,而该父目录又递归清除所有子目录,而不必在每个子目录中都包含makefile?
例如,当前在我的Makefile中,我有类似以下内容:
1 2 3 4 5 6 7 8 9 |
SUBDIRS = src, src1 .PHONY: clean subdirs $(SUBDIRS) clean: $(SUBDIRS) rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c $(SUBDIRS): $(MAKE) -C $(SUBDIRS) clean |
但是,这要求我在src和src1中都具有一个Makefile。 否则,我会得到错误
1 | No rule to make target clean |
由于我仍然只想在每个子目录中运行命令" rm -rf * .o?core .depend ..cmd * .ko * .mod.c",因此似乎不得不在每个子目录中都包含一个Makefile,这是多余的。 完全相同的线清洁。 没有办法简单地在每个子目录中运行相同的clean命令吗?
相关讨论
- 您可能只想让clean命令以递归方式删除文件。 参见:superuser.com/questions/61258/
- 或只是循环循环遍历$(SUBDIRS)并手动运行每个rm。
- 实际上,如果您仔细地编写顶级Makefile(或编写包含的单独的clean.mk makefile),那么我认为可以在该配方中$(MAKE) -C $@ -f clean.mk clean。 (注意$@而不是$(SUBDIRS)。-C接受单个参数而不是列表。)
- 您将在子make上获得SUBDIRS变量的副本,这会破坏过程的递归部分。 仅当您具有相同的子目录(具有相同的名称)时,该计划才有效。
我同意您可以只对子目录执行rm命令。但是类似以下的内容仅允许使用单个makefile进行递归make:
1 2 3 4 5 6 7 8 9 10 |
SUBDIRS = . src src1 SUBDIRSCLEAN=$(addsuffix clean,$(SUBDIRS)) clean: $(SUBDIRSCLEAN) clean_curdir: rm -rfv *.o *~ core .depend .*.cmd *.ko *.mod.c %clean: % $(MAKE) -C $< -f $(PWD)/Makefile clean_curdir |
- 您如何在src或src1中递归一次?您如何知道其中有多少个子目录并构造变量SUBDIRS的新版本?
- 该示例已完成。 运行make --debug将显示正在发生的事情。 如果硬编码列表不起作用,则类似find的东西可能会检测到子目录。
除了使用递归,您还可以使用find来获取目录列表,并进行一次迭代以生成通配符:
1 2 3 4 5 6 7 |
SUBDIR_ROOTS := foo bar DIRS := . $(shell find $(SUBDIR_ROOTS) -type d) GARBAGE_PATTERNS := *.o *~ core .depend .*.cmd *.ko *.mod.c GARBAGE := $(foreach DIR,$(DIRS),$(addprefix $(DIR)/,$(GARBAGE_PATTERNS))) clean: rm -rf $(GARBAGE) |
@Christoph答案的变体:
1 2 3 4 5 6 7 8 9 |
# Exclude directory from find . command # https://stackoverflow.com/questions/4210042/exclude-directory-from-find-command GARBAGE_TYPES :="*.gz(busy)" *.aux *.log *.pdf *.aux *.bbl *.log *.out *.synctex.gz *.fls DIRECTORIES_TO_CLEAN := $(shell find -not -path"./.git**" -not -path"./images**" -type d) GARBAGE_TYPED_FOLDERS := $(foreach DIR, $(DIRECTORIES_TO_CLEAN), $(addprefix $(DIR)/,$(GARBAGE_TYPES))) clean: $(RM) -rf $(GARBAGE_TYPED_FOLDERS) # echo $(GARBAGE_TYPED_FOLDERS) |
这是乳胶文件的示例。由于文件类型名称上的括号,GARBAGE_TYPES上的第一个模式用双引号引起来。没有它,rm无法删除它们。其他模式不需要引号。
第二个DIRECTORIES_TO_CLEAN使用与要清除的目录列表相反的内容,即,要清除的目录列表。当您只有一个或两个目录(.git和images)不想清理,但又想清理其他所有内容时,此功能很有用。
您不能没有外部程序的帮助。最好的方法是在每个子目录中执行递归和调用的shell脚本(请看我对@robert的评论),这样的事情就可以完成工作(并且不依赖于GNU make功能)
1 2 3 4 5 6 |
#!/bin/sh ROOTDIR=`/bin/pwd` for dir in `find . -type d -print` do make -C"${dir}" -f"${ROOTDIR}"/Makefile clean done |
当然,您可以将此序列(在目标cleanrec中)放入您的Makefile
1 2 3 4 5 6 |
cleanrec: ROOT=`/bin/pwd`; \ for dir in `find . -type d -print`; \ do \ make -C"$${dir}" -f"$${ROOTDIR}"/Makefile clean; \ done |
并保存您的clean目标,以便在本地清理单个目录。原因是Makefile仅具有静态信息来执行make,并且您必须获得一些外部帮助才能知道每个目录中都有哪些子目录。因此,如果您要获得外部帮助,则最好使用find(1)和sh(1)这样的好工具
from: https://www.codenong.com/26007005/
标签:子目录,make,Makefile,SUBDIRS,编译,clean,find From: https://www.cnblogs.com/im18620660608/p/17778498.html