Using Makefile to Clean Subdirectories

Is it possible to do make clean from the parent directory, which also recursively cleans all subdirectories without having to include the makefile in each subdirectory?

For example, currently in my Makefile I have something like:

SUBDIRS = src, src1 .PHONY: clean subdirs $(SUBDIRS) clean: $(SUBDIRS) rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c $(SUBDIRS): $(MAKE) -C $(SUBDIRS) clean 

However, this requires that I have a Makefile in src and src1. Otherwise, I get an error

 No rule to make target clean 

Since I always want to run the command "rm -rf * .o ~ core.depend..cmd * .ko * .mod.c" in any subdirectory, it seems unnecessary to include the Makefile in each subdirectory with the same line for cleaning. Is there no way to just execute the same clean command in each of the subdirectories?

+5
source share
4 answers

Instead of using recursion, you can run the find to get a list of directories and do one iteration to create wildcards:

 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) 
+1
source

I agree that you can just use the rm command for subdisks. But something like the following allows a recursive make using only one make file:

 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 
0
source

You cannot without the help of an external program. Best is a shell script that does recursion and calls in each of the subdirectories (look at my comment on @robert in his answer). Something like this will do the job (and is independent of GNU make functions)

 #!/bin/sh ROOTDIR=`/bin/pwd` for dir in `find . -type d -print` do make -C "${dir}" -f "${ROOTDIR}"/Makefile clean done 

of course you can put this sequence (in the cleanrec target) inside your Makefile

 cleanrec: ROOT=`/bin/pwd`; \ for dir in `find . -type d -print`; \ do \ make -C "$${dir}" -f "$${ROOTDIR}"/Makefile clean; \ done 

and save the clean target to locally clean one directory. The reason is that the Makefile has only static information to do make, and you need to get external help to find out which subdirectories you have in each directory. So, if you are going to get external help, it is better to use a good tool like find (1) and sh (1)

0
source

@Christoph answer option :

 # 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) 

This is an example for latex files. The first template on GARBAGE_TYPES has double quotes around it due to the parenthesis in the file type name. Without it, rm cannot delete them. Other patterns do not need quotation marks.

The second DIRECTORIES_TO_CLEAN uses the opposite of the directory list to clear, i.e. list of directories that are not cleared. This is useful if you have only one or two directories like .git and images , which you do not want to clear, but want to clear everything else.

0
source

Source: https://habr.com/ru/post/1203266/


All Articles