web-dev-qa-db-fra.com

Puis-je compiler tous les fichiers .cpp dans src / en .o dans obj /, puis créer un lien vers un fichier binaire dans ./?

Mon répertoire de projet ressemble à ceci:

/project
    Makefile
    main
    /src
        main.cpp
        foo.cpp
        foo.h
        bar.cpp
        bar.h
    /obj
        main.o
        foo.o
        bar.o

Ce que je voudrais que mon makefile fasse serait de compiler tous les fichiers .cpp Du dossier /src En fichiers .o Du dossier /obj, Puis de les lier à tous. les fichiers .o dans /obj dans le binaire de sortie du dossier de niveau supérieur /project.

Je n'ai pratiquement aucune expérience avec Makefiles et je ne sais pas trop quoi chercher pour accomplir cela.

Aussi, est-ce une "bonne" façon de faire cela, ou existe-t-il une approche plus standardisée de ce que j'essaie de faire?

110
Austin Hyde

Makefile partie de la question

C'est assez facile, à moins que vous n'ayez pas besoin de généraliser, essayez quelque chose comme le code ci-dessous (mais remplacez l'indentation d'espace par des tabulations proches de g ++)

SRC_DIR := .../src
OBJ_DIR := .../obj
SRC_FILES := $(wildcard $(SRC_DIR)/*.cpp)
OBJ_FILES := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRC_FILES))
LDFLAGS := ...
CPPFLAGS := ...
CXXFLAGS := ...

main.exe: $(OBJ_FILES)
   g++ $(LDFLAGS) -o $@ $^

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
   g++ $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<

Génération automatique de graphes de dépendance

Un "must" caractéristique pour la plupart des systèmes de marque. Avec GCC, l'entrée peut être effectuée en un seul passage comme effet secondaire de la compilation en ajoutant l'indicateur -MMD À CXXFLAGS et -include $(OBJ_FILES:.o=.d) à la fin du corps du fichier Make:

CXXFLAGS += -MMD
-include $(OBJ_FILES:.o=.d)

Et comme les gars l'ont déjà mentionné, ayez toujours GNU Make Manual , c'est très utile.

173
bobah

Wildcard fonctionne aussi pour moi, mais j'aimerais donner une note complémentaire à ceux qui utilisent des variables de répertoire. Toujours utiliser la barre oblique pour l’arborescence des dossiers (pas la barre oblique inverse), sinon cela échouera:

BASEDIR = ../..
SRCDIR = $(BASEDIR)/src
INSTALLDIR = $(BASEDIR)/lib

MODULES = $(wildcard $(SRCDIR)/*.cpp)
OBJS = $(wildcard *.o)
5
xesf