GNU/Linux >> Tutoriels Linux >  >> Linux

Makefiles avec des fichiers source dans différents répertoires

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

Linux
  1. Rechercher des fichiers et des répertoires sous Linux avec la commande find

  2. Comment compresser des fichiers et des répertoires sous Linux (avec exemples)

  3. Copier des fichiers et des répertoires sous Linux

  4. Trouver les plus gros fichiers ou répertoires ?

  5. Linux - Différents formats de fichiers objets sous Linux ?

Comment exclure des fichiers et des répertoires avec Rsync

Créer des répertoires ou des fichiers nommés avec la date/l'heure/le mois/l'année actuels

Synchronisation des fichiers et répertoires Linux avec rsync

Principes de base de la ligne de commande Linux - Travailler avec des fichiers et des répertoires

Comment mettre en miroir un répertoire avec wget sans créer de répertoires parents ?

Créer une nouvelle arborescence de répertoires vide à partir de l'arborescence existante avec des fichiers