Il modo tradizionale è avere un Makefile
in ciascuna delle sottodirectory (part1
, part2
, ecc.) permettendoti di costruirli in modo indipendente. Inoltre, prendi un Makefile
nella directory principale del progetto che costruisce tutto. La "radice" Makefile
sarebbe simile al seguente:
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Dal momento che ogni riga in un target di make viene eseguita nella propria shell, non c'è bisogno di preoccuparsi di tornare indietro nell'albero delle directory o in altre directory.
Suggerisco di dare un'occhiata alla sezione 5.7 del manuale GNU make; è molto utile.
Puoi aggiungere regole al tuo Makefile root per compilare i file cpp necessari in altre directory. L'esempio di Makefile qui sotto dovrebbe essere un buon inizio per portarti dove vuoi essere.
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)
L'opzione VPATH potrebbe tornare utile, che dice a make in quali directory cercare il codice sorgente. Tuttavia, avresti comunque bisogno di un'opzione -I per ogni percorso di inclusione. Un esempio:
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
Questo troverà automaticamente i file partXapi.cpp corrispondenti in una qualsiasi delle directory specificate da VPATH e li compilerà. Tuttavia, questo è più utile quando la tua directory src è suddivisa in sottodirectory. Per quello che descrivi, come altri hanno già detto, probabilmente stai meglio con un makefile per ogni parte, specialmente se ogni parte può stare da sola.
Se hai codice in una sottodirectory dipendente dal codice in un'altra sottodirectory, probabilmente stai meglio con un singolo makefile al livello più alto.
Vedi Recursive Make Considered Harmful per la logica completa, ma fondamentalmente vuoi che make disponga delle informazioni complete di cui ha bisogno per decidere se un file deve essere ricostruito o meno, e non lo avrà se gli dici solo circa un terzo di il tuo progetto.
Il link sopra sembra non essere raggiungibile. Lo stesso documento è raggiungibile qui:
- aegis.sourceforge.net (archiviato)
- lcgapp.cern.ch