是否可以从父目录执行make clean,它也可以递归清理所有子目录,而不必在每个子目录中包含makefile?
例如,目前在我的Makefile中,我有类似的东西:
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。否则,我会收到错误
No rule to make target clean
因为我只想在每个子目录中运行命令“rm -rf * .o ~core .depend。 .cmd * .ko * .mod.c”,所以似乎多余了必须在每个子目录中包含一个Makefile,并使用完全相同的行进行清理。是不是只能在每个子目录中运行相同的清洁命令?
答案 0 :(得分:1)
我同意你可以让rm命令对子目录进行操作。但是类似下面的内容允许仅使用单个makefile进行递归make:
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
答案 1 :(得分:1)
不是使用递归,而是可以向find
发送shell以获取目录列表并执行单次迭代以生成通配符:
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)
答案 2 :(得分:0)
你不能没有外部程序的帮助。最好的是一个shell脚本,它在每个子目录中执行递归和调用make(在他的响应中查看我对@robert的评论)这样的事情将完成工作(并且不依赖于GNU make功能)
#!/bin/sh
ROOTDIR=`/bin/pwd`
for dir in `find . -type d -print`
do
make -C "${dir}" -f "${ROOTDIR}"/Makefile clean
done
当然,您可以将此序列(在目标cleanrec
中)放在Makefile
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)
答案 3 :(得分:0)
@Christoph答案的变体:
# 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
时,如果您不想清理这些目录,但想清除其他所有目录,这非常有用。
答案 4 :(得分:0)
ALL_MOD = $(shell find . -maxdepth 1 -type d )
ALL_MOD_CLEAN = $(addsuffix .clean, $(ALL_MOD))
.PHONY: $(ALL_MOD_CLEAN) $(ALL_MOD) default all clean
$(ALL_MOD_CLEAN):
$(E) "cleaning $(basename $@)"
if [ -e $(basename $@)/Makefile ] ; then \
$(MAKE) -C $(basename $@) clean ;\
fi
clean: $(ALL_MOD_CLEAN)
$(E) "cleaning complete: " $(ALL_MOD)
添加“。”后缀并使用$(basename ...)代替原始目标,否则每次需要清理项目时都会重新制作所有文件