2014-09-24 10 views
5

Ist es möglich, eine Bereinigung aus dem übergeordneten Verzeichnis durchzuführen, die auch alle Unterverzeichnisse rekursiv löscht, ohne ein Makefile in jedem Unterverzeichnis aufzunehmen?Makefile verwenden, um Unterverzeichnisse zu bereinigen

Zum Beispiel zur Zeit in meinem Makefile habe ich so etwas wie:

SUBDIRS = src, src1 

.PHONY: clean subdirs $(SUBDIRS) 

clean: $(SUBDIRS) 
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c 

$(SUBDIRS): 
    $(MAKE) -C $(SUBDIRS) clean 

Dies erfordert jedoch ich ein Makefile in beiden src und src1 zu haben. Ansonsten würde ich den Fehler

No rule to make target clean 

Da ich nur den Befehl "rm -rf * .o ~ Kern .depend. .cmd * .ko * .mod.c" ausgeführt werden soll in jedem Unterverzeichnis Wie dem auch sei, es scheint redundant zu sein, ein Makefile in jedes Unterverzeichnis mit der exakt gleichen Zeile für clean einzufügen. Gibt es keine Möglichkeit, in jedem der Unterverzeichnisse denselben clean-Befehl auszuführen?

+0

Sie möchten wahrscheinlich nur den Befehl clean löschen Dateien rekursiv löschen. Siehe: https: // Superuser.com/questions/61258/use-rm-to-remove-files-and-directories-recursively –

+0

Das oder einfach loop rein über '$ (SUBDIRS)' und führen Sie 'rm' in jedem manuell. –

+0

Eigentlich, wenn Sie Ihre Makefile Toplevel sorgfältig schreiben (oder schreiben Sie eine separate 'clean.mk' Makefile, die Sie einschließen), dann können Sie' $ (MAKE) -C $ @ -f clean.mk clean' in diesem Rezept, denke ich. (Beachten Sie '$ @' anstelle von '$ (SUBDIRS)'. '-C' nimmt ein einzelnes Argument und keine Liste.) –

Antwort

0

Ich stimme zu, dass Sie einfach den Befehl rm auf Subdirects arbeiten lassen können. Aber so etwas wie die folgenden erlaubt rekursive make nur eine einzige Make-Datei mit:

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

Wie werden Sie einmal in src oder src1 recurse ... woher wissen Sie, wie viele Unterverzeichnisse da sind und eine neue Version der Variablen 'SUBDIRS' konstruieren? –

+0

Das Beispiel ist abgeschlossen. Running 'make --debug' zeigt an, was passiert. Etwas wie 'find' könnte die Unterverzeichnisse wahrscheinlich erkennen, wenn eine hart codierte Liste nicht funktioniert. – robert

0

Sie können nicht ohne Hilfe eines externen Programms. Das beste ist ein Shell-Skript, das die Rekursion ausführt und Aufrufe in jedem der Unterverzeichnisse macht (siehe meinen Kommentar zu @robert in seiner Antwort). So etwas macht die Arbeit (und hängt nicht von GNU make-Funktionen ab)

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

natürlich, können Sie diese Reihenfolge gebracht (in Ziel cleanrec) in Ihrem Makefile

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

und schonen Ihre clean Ziel für die lokale Reinigung eines einzigen Verzeichnis. Der Grund ist, dass Makefile nur statische Informationen hat, um das make zu machen, und Sie müssen eine externe Hilfe bekommen, um zu wissen, welche Unterverzeichnisse Sie in jedem Verzeichnis haben. Also, falls wollen Sie externe Hilfe bekommen, ist besser, ein gutes Werkzeug wie Fund zu verwenden (1) und sh (1)

1

Statt Rekursion zu verwenden, können Sie berappen zu find eine Liste von Verzeichnissen zu erhalten und eine einzige Iteration tun, um die Platzhalter zu generieren:

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

eine Variation @Christoph Antwort:

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

Dies ist ein exampl e für Latexdateien. Das erste Muster auf GARBAGE_TYPES hat die doppelten Anführungszeichen um es wegen der Klammer auf dem Dateitypename. Ohne es kann rm sie nicht entfernen. Die anderen Muster benötigen keine Anführungszeichen.

Die zweite DIRECTORIES_TO_CLEAN verwendet das Gegenteil einer Liste von Verzeichnissen zu bereinigen, d. H. Eine Liste von Verzeichnissen nicht zu bereinigen. Dies ist nützlich, wenn Sie nur ein oder zwei Verzeichnisse wie .git und images haben, die Sie nicht löschen möchten, aber alles andere löschen möchten.

Verwandte Themen