Wie könnte man folgendes Makefile noch weiter automatisieren...
-
Hallo,
ich habe vor einer Weile damit angefangen in C++ zu programmieren und wollte mir jetzt eine Bibliothek schreiben, welche mir das lästige hin und her kopieren von Sourcen ersparen soll. Dazu habe ich ein Beispielprojekt angelegt und einfach stupide ein Makefile dafür geschrieben und ein klein wenig optimiert. Herausgekommen ist folgendes:LIB_SONAME = libde-jtdev-base.so.1 LIB_REALNAME = libde-jtdev-base.so.1.0.0 COMPILER = g++ LIBRARIES = OBJECT_FILES = \ src/de/jtdev/base/collections/Iterator.o \ src/de/jtdev/base/collections/Iterable.o \ src/de/jtdev/base/collections/Collection.o \ src/de/jtdev/base/collections/List.o \ # Erstellen der Bibliothek aus den Object-Dateien # gcc -shared -Wl,-soname,the_soname -o library_name file_list library_list dist/$(LIB_REALNAME): $(OBJECT_FILES) $(COMPILER) -shared -Wl,-soname,$(LIB_SONAME) -o $@ $^ $(LIBRARIES) # Erstellen der Object-Dateien, welche jeweils von einer gleichnamigen cpp und # hpp abhängen. # gcc -fPIC -g -Wall -c -o oname *.cpp src/de/jtdev/base/collections/Iterator.o: src/de/jtdev/base/collections/Iterator.cpp src/de/jtdev/base/collections/Iterator.hpp $(COMPILER) -fPIC -g -Wall -c -o $@ $< src/de/jtdev/base/collections/Iterable.o: src/de/jtdev/base/collections/Iterable.cpp src/de/jtdev/base/collections/Iterable.hpp $(COMPILER) -fPIC -g -Wall -c -o $@ $< src/de/jtdev/base/collections/Collection.o: src/de/jtdev/base/collections/Collection.cpp src/de/jtdev/base/collections/Collection.hpp $(COMPILER) -fPIC -g -Wall -c -o $@ $< src/de/jtdev/base/collections/List.o: src/de/jtdev/base/collections/List.cpp src/de/jtdev/base/collections/List.hpp $(COMPILER) -fPIC -g -Wall -c -o $@ $< # Abhängigkeiten der Headerdateien untereinander. Diese können aus dem Headern # der Dateien extrahiert werden. Da der Header immer regelmäßig aufgebaut ist, # sollte sich der Aufwand wesentlich vereinfachen. src/de/jtdev/base/collections/Iterator.hpp: src/de/jtdev/base/collections/Iterable.hpp: src/de/jtdev/base/collections/Iterator.hpp src/de/jtdev/base/collections/Collection.hpp: src/de/jtdev/base/collections/Iterator.hpp src/de/jtdev/base/collections/Iterable.hpp src/de/jtdev/base/collections/List.hpp: src/de/jtdev/base/collections/Collection.hpp
Was jedem wohl auffallen dürfte ist die unglaubliche Redundanz
Da mein Code ja in einer Hierachie vorliegt bräuchte ich als erstes einmal eine Funktion welche rekursiv die Verzeichnisse unterhalb von "src" durchläuft und mir eine Liste der Dateinamen (OBJECT_FILES) ohne Endung erstellt. Dadurch würde der mittlere Teil des Makefiles auf 2 Zeilen reduziert werden.Allerdings habe ich ein Problem. Ich weiß einfach nicht wie ich das in Make anstellen soll. Wie ich mitbekommen habe versteht Make ja Skripte, nur ich habe absolut keine Idee wie ich hier rangehen soll.
Als Bonus bräuchte ich noch irgendetwas was mir die Headerdateien durchsucht und entsprechende Abhängigkeiten automatisch erstellt und ins Makefile inkludiert.
Helft mir bitte, egal wie...
mfg Tobain
-
Schau Dir einfach mal die autotools oder scons oä an; sowas löst man idR mit rekursiven Makes.
-
Das habe ich ja auch schon getan, allerdings belassen diese Varianten die *.o Dateien nicht im selben Verzeichnis wie die *.cpp Dateien. Dies ist bei mir allerdings problematisch, da ich durchaus mehrere SourceFiles mit dem gleichen Namen habe, die aber in verschiedenen Ordnern liegen.
Aus diesem Grund wollte ich mir ja zunächst eine Liste aller zu übersetzender Dateien besorgen. Jede Datei an ihrem Ort übersetzen und anschließend diese zu einer Library zusammenfassen. (Damit Objekte intern nicht die gleichen Namen haben, habe ich sie durch entsprechende Namespaces voneinander abgeschottet.)
Jetzt fehlt mir halt irgendwie ein Stück Source mit dessen Hilfe ich die Dateien rekursiv sammeln kann. Ich möchte hier auch möglichst auf ein rekursives Aufrufen von Make verzichten.
-
Dann sammel einfach via man: find(1).
-
Ich muss Zugeben das ich mit der Konsole noch arg am Kämpfen bin. Denn ich bekomme es einfach nicht hin die Ausgabe von man: find(1) so umzuwandeln das er mir einfach die Zeilenumbrüche durch Leerzeichen ersetzt
Kann man sed dafür benutzen, oder arbeitet dieser nur zeilenorientiert?
-
ein find | tr '\n' ' ' sollte das tun, was du willst.
Ein einfaches makefile, das in etwa tut was du willst, ist das (gmake):DIRS := bla blub foo bla_SOURCES := test.bla.c blub_SOURCES := test.blub.c foo_SOURCES := test.foo.c LIB=foo.bla.blub.so ########################################### SRCS=$(foreach dir, $(DIRS), $(foreach src, $($(dir)_SOURCES), $(dir)/$(src))) OBJS=$(subst .c,.o,$(SRCS)) $(LIB): $(OBJS) gcc -shared -fPIC -DPIC -o $(LIB) $(OBJS) all: $(LIB) @echo $(SRCS) @echo $(OBJS) define OBJ_TEMPL $(1): $(subst .o,.c,$(1)) gcc -c -shared -fPIC -DPIC -o $(1) $(subst .o,.c,$(1)) endef $(foreach obj,$(OBJS),$(eval $(call OBJ_TEMPL,$(obj)))) clean: rm -f $(OBJS) $(LIB)
Natürlich ist es nicht genau das, was dein makefile macht, aber das ist auch nur eines von meinen testmakefiles. Sollte sich leicht ausbauen lassen.
-
Tobain schrieb:
Das habe ich ja auch schon getan, allerdings belassen diese Varianten die *.o Dateien nicht im selben Verzeichnis wie die *.cpp Dateien. Dies ist bei mir allerdings problematisch, da ich durchaus mehrere SourceFiles mit dem gleichen Namen habe, die aber in verschiedenen Ordnern liegen.
Dann mach mal:
AM_INIT_AUTOMAKE([subdir-objects])