[makefile] automatisch Subfolder suchen und nach h- und c-Dateien durchsuchen
-
Hallo c-community,
ich möchte meine Arbeit bei der Aktualisierung meiner Makefiles automatisieren. Ich arbeite derzeit mit einem Unterordner in welchem alle Sourcefiles liegen und muss bei neuen h- und c-Dateien händisch diese in meine Makefile einpflegen. Dies würde ich gern automatisieren. Leider bleibe ich derzeit immer an (glaube ich) einfachen Problemen hängen.
Hier mal eine aktuelle Makefile von mir:
VERSION = 0.0.0.1 CC = gcc CFLAGS = -ggdb -Wall -Werror -O0 -DVERSION=\"$(VERSION)\" LDFLAGS = -lpthread ODIR = obj CLASSES_SDIR = classes/src CLASSES_IDIR = classes/header CLASSES__DEPS = listelement.h list.h object.h process.h event.h CLASSES_DEPS = $(patsubst %,$(CLASSES_IDIR)/%,$(CLASSES__DEPS)) CLASSES__OBJ = listelement.o list.o object.o process.o event.o CLASSES_OBJ = $(patsubst %,$(ODIR)/%,$(CLASSES__OBJ)) $(ODIR)/%.o: $(CLASSES_SDIR)/%.c $(CLASSES_DEPS) $(CC) -c -o $@ $< $(CFLAGS) COM_SDIR = src COM_IDIR = header COM__DEPS = main.h COM_DEPS = $(patsubst %,$(COM_IDIR)/%,$(COM__DEPS)) COM__OBJ = main.o COM_OBJ = $(patsubst %,$(ODIR)/%,$(COM__OBJ)) $(ODIR)/%.o: $(COM_SDIR)/%.c $(COM_DEPS) $(CC) -c -o $@ $< $(CFLAGS) programm: $(COM_OBJ) $(CLASSES_OBJ) $(CC) -o $@ $+ $(CFLAGS) $(LDFLAGS) .PHONY: clean clean: rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
Hier gut zu sehen: 1.) für jeden Unterordner müssen mehrere Zeilen ergänzt und 2.) jede h- und c-Datei muss händisch ergänzt werden.
Dies möchte ich ändern. Ich habe im ersten Schritt versucht die h-Dateien automatisch im Ordner suchen zu lassen aber dies scheint nicht wie gewünscht zu funktionieren:CLASSES__DEPS = $(shell find $(CLASSES__DEPS) -type f -name "\*.h")
Hoffe jemand kann hier den ein oder anderen Ansatz zeigen, wie man diese Probleme lösen kann.
Vielen Dank
mirrowwinger
-
probier die make wildcard funktion
MY_FILES = $(wildcard *.h)
http://www.gnu.org/software/make/manual/html_node/Wildcard-Function.html#Wildcard-Function
-
-
Hallo nochmal c-community,
sorry dass ich mich erst jetzt auf die Beiträge antworten kann. Also erstmal an ScottZhang und SeppJ vielen Dank für die Beiträge. Leider war der Verweis von SeppJ nicht sehr hilfreich, da das Thema ja eigentlich makefile mit Subfoldern heißt. Aber trotzdem haben mir einige Zeilen in der Makefile für die Recherche geholfen. Die Wildcard ist auch nicht schlecht aber schlussendlich habe ich ersteinmal folgende Makefile aus mehreren Internetbeiträgen geschrieben:
VERSION = 0.0.1 CC = gcc WARNINGS = -Wall -Wextra -Werror -pedantic -Wshadow -Wpointer-arith -Wcast-align \ -Wwrite-strings -Wmissing-prototypes -Wmissing-declarations \ -Wredundant-decls -Wnested-externs -Winline -Wno-long-long \ -Wuninitialized -Wconversion -Wstrict-prototypes DEBUG = -ggdb CFLAGS = -std=c99 $(WARNINGS) $(DEBUG) -DVERSION=\"$(VERSION)\" LDFLAGS = -lpthread BUILD = build SOURCE = sources BINARY = name VPATH = $(shell find $(SOURCE) -name '*.h' -exec dirname {} \; | uniq) SOURCES_FILENAME = $(shell find $(SOURCE) -name '*.c' -exec basename {} \; | uniq) SOURCES_OBJECTNAME = $(patsubst %.c, %.o, $(SOURCES_FILENAME)) SOURCES_OBJECTS = $(patsubst %, $(BUILD)/%, $(SOURCES_OBJECTNAME)) $(BUILD)/%.o: %.c %.h @mkdir -p $(BUILD) $(CC) -c -o $@ $< $(CFLAGS) $(BINARY): $(SOURCES_OBJECTS) $(CC) -o $@ $+ $(CFLAGS) $(LDFLAGS) .PHONY: setup clean setup: mkdir -p $(BUILD) clean: @$(RM) -rf $(BINARY) $(SOURCES_OBJ) $(BUILD)
Mit VPATH spare ich mir das zusammenschnipseln der Pfade und Quelldateien. Mit find werden alle c-Dateien (basename = nur Dateiname) gesucht (auch in Unterverzeichnissen) und in o-Dateien im BUILD-Ordner erstellt. Einziges Manko ist noch, dass bei Ausführung von:
make test.o
Die o-Datei nicht automatisch im BUILD-Ordner gelegt wird sondern ins Verzeichnis der Makefile. Bei normalem make:
make
wird wie gewünscht alles ins BUILD-Verzeichnis gelegt und die BINARY erzeugt.
Vieleicht kann mir ja jemand noch helfen diesen kleinen Fehler zu beseitigen, sonst kann ich aber auch damit jetzt leben.Vielen Dank
mirrowwinger
-
mirrowwinger schrieb:
Einziges Manko ist noch, dass bei Ausführung von:
make test.o
Die o-Datei nicht automatisch im BUILD-Ordner gelegt wird sondern ins Verzeichnis der Makefile.
Ja, make sucht ein Target für "test.o", findet keines und nimmt das Default-Target. Lass mich raten, die test.c liegt auch im selben Verzeichnis?
Die Default-Regeln kannst du durch ein leeres Suffixes entfernen:.SUFFIXES:
durch ein "make build/test.o" hättest du dein gewünschtes Verhalten. Wäre ja ein Unding, wenn "make foo" ausführen würde. Dann müsste ich ja wieder umständlich nach $foo suchen.
-
@oenone:
Nein meine Struktur sieht ungefähr so aus:Projektordner | |- makefile |- build/ // <-- enthält all .o-Dateien | |- test.o | |- test2.o | |- main.o | |- sources/ // <-- enhält alle .c- und .h-Dateien auch in weiteren Unterverzeichnissen | |- Unterordner1 | | |- test.c | | |- test.h | |- Unterordner2 | | |- test2.c | | |- test2.h | |- main.c | |- main.h
.
Die .o-Dateien werden also mit:make
richtig ins build/-Verzeichnis abgelegt. Bei
make test.o
soll dies eigentlich auch so sein aber es wird im Projektordner abgelegt. Ich hoffe die Darstellung macht das Problem deutlicher. Aber natürlich macht dein Einwand auch Sinn, dass
make test.o
und
make build/test.o
sich unterscheiden sollten.