La manière traditionnelle est d'avoir un Makefile
dans chacun des sous-répertoires (part1
, part2
, etc.) vous permettant de les construire indépendamment. De plus, avoir un Makefile
dans le répertoire racine du projet qui construit tout. La "racine" Makefile
ressemblerait à ceci :
all:
+$(MAKE) -C part1
+$(MAKE) -C part2
+$(MAKE) -C part3
Étant donné que chaque ligne d'une cible make est exécutée dans son propre shell, il n'est pas nécessaire de s'inquiéter de remonter l'arborescence des répertoires ou vers d'autres répertoires.
Je suggère de jeter un œil à la section 5.7 du manuel GNU make; c'est très utile.
Vous pouvez ajouter des règles à votre Makefile racine afin de compiler les fichiers cpp nécessaires dans d'autres répertoires. L'exemple Makefile ci-dessous devrait être un bon début pour vous amener là où vous voulez être.
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'option VPATH peut être utile, car elle indique à make dans quels répertoires rechercher le code source. Cependant, vous aurez toujours besoin d'une option -I pour chaque chemin d'inclusion. Un exemple :
CXXFLAGS=-Ipart1/inc -Ipart2/inc -Ipart3/inc
VPATH=part1/src:part2/src:part3/src
OutputExecutable: part1api.o part2api.o part3api.o
Cela trouvera automatiquement les fichiers partXapi.cpp correspondants dans l'un des répertoires spécifiés par VPATH et les compilera. Cependant, cela est plus utile lorsque votre répertoire src est divisé en sous-répertoires. Pour ce que vous décrivez, comme d'autres l'ont dit, vous feriez probablement mieux d'avoir un makefile pour chaque partie, surtout si chaque partie peut être autonome.
Si vous avez du code dans un sous-répertoire dépendant du code dans un autre sous-répertoire, vous feriez probablement mieux avec un seul makefile au niveau supérieur.
Voir Recursive Make Considered Harmful pour la justification complète, mais fondamentalement, vous voulez que make ait toutes les informations dont il a besoin pour décider si un fichier doit être reconstruit ou non, et il n'en aura pas si vous ne lui dites qu'environ un tiers de votre projet.
Le lien ci-dessus semble inaccessible. Le même document est accessible ici :
- aegis.sourceforge.net (archivé)
- lcgapp.cern.ch