Der traditionelle Weg ist ein Makefile
in jedem der Unterverzeichnisse (part1
, part2
, usw.), sodass Sie sie unabhängig voneinander erstellen können. Außerdem haben Sie eine Makefile
im Stammverzeichnis des Projekts, das alles erstellt. Der "Stamm" Makefile
würde in etwa so aussehen:
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Da jede Zeile in einem make-Target in ihrer eigenen Shell ausgeführt wird, müssen Sie sich keine Gedanken darüber machen, den Verzeichnisbaum oder andere Verzeichnisse zu sichern.
Ich schlage vor, einen Blick in den Abschnitt 5.7 des GNU-Make-Handbuchs zu werfen; es ist sehr hilfreich.
Sie können Ihrem Root-Makefile Regeln hinzufügen, um die erforderlichen cpp-Dateien in anderen Verzeichnissen zu kompilieren. Das folgende Makefile-Beispiel sollte ein guter Anfang sein, um Sie dorthin zu bringen, wo Sie sein möchten.
CC=g++ TARGET=cppTest OTHERDIR=../../someotherpath/in/project/src SOURCE = cppTest.cpp SOURCE = $(OTHERDIR)/file.cpp ## End sources definition INCLUDE = -I./ $(AN_INCLUDE_DIR) INCLUDE = -I.$(OTHERDIR)/../inc ## end more includes VPATH=$(OTHERDIR) OBJ=$(join $(addsuffix ../obj/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.o))) ## Fix dependency destination to be ../.dep relative to the src dir DEPENDS=$(join $(addsuffix ../.dep/, $(dir $(SOURCE))), $(notdir $(SOURCE:.cpp=.d))) ## Default rule executed all: $(TARGET) @true ## Clean Rule clean: @-rm -f $(TARGET) $(OBJ) $(DEPENDS) ## Rule for making the actual target $(TARGET): $(OBJ) @echo "=============" @echo "Linking the target [email protected]" @echo "=============" @$(CC) $(CFLAGS) -o [email protected] $^ $(LIBS) @echo -- Link finished -- ## Generic compilation rule %.o : %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o [email protected] ## Rules for object files from cpp files ## Object file for each file is put in obj directory ## one level up from the actual source directory. ../obj/%.o : %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o [email protected] # Rule for "other directory" You will need one per "other" dir $(OTHERDIR)/../obj/%.o : %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o [email protected] ## Make dependancy rules ../.dep/%.d: %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo Building dependencies file for $*.o @$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^../obj/$*.o^" > [email protected]' ## Dependency rule for "other" directory $(OTHERDIR)/../.dep/%.d: %.cpp @mkdir -p $(dir [email protected]) @echo "=============" @echo Building dependencies file for $*.o @$(SHELL) -ec '$(CC) -M $(CFLAGS) $< | sed "s^$*.o^$(OTHERDIR)/../obj/$*.o^" > [email protected]' ## Include the dependency files -include $(DEPENDS)
Die VPATH-Option könnte nützlich sein, die make mitteilt, in welchen Verzeichnissen nach Quellcode gesucht werden soll. Sie benötigen jedoch immer noch eine -I-Option für jeden Include-Pfad. Ein Beispiel:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
Dadurch werden automatisch die passenden partXapi.cpp-Dateien in einem der vom VPATH angegebenen Verzeichnisse gefunden und kompiliert. Dies ist jedoch nützlicher, wenn Ihr src-Verzeichnis in Unterverzeichnisse aufgeteilt ist. Für das, was Sie beschreiben, sind Sie, wie andere gesagt haben, wahrscheinlich besser dran mit einem Makefile für jeden Teil, besonders wenn jeder Teil alleine stehen kann.
Wenn Sie Code in einem Unterverzeichnis haben, der von Code in einem anderen Unterverzeichnis abhängig ist, sind Sie wahrscheinlich mit einem einzigen Makefile auf oberster Ebene besser dran.
Die vollständige Begründung finden Sie unter Rekursives Make gilt als schädlich, aber im Grunde möchten Sie, dass make alle Informationen hat, die es benötigt, um zu entscheiden, ob eine Datei neu erstellt werden muss oder nicht, und das wird es nicht haben, wenn Sie ihm nur etwa ein Drittel davon mitteilen Ihr Projekt.
Der obige Link scheint nicht erreichbar zu sein. Das gleiche Dokument ist hier erreichbar:
- aegis.sourceforge.net (archiviert)
- lcgapp.cern.ch