La plupart des réponses sont étonnamment compliquées ou erronées. Cependant, des exemples simples et solides ont été postés ailleurs [ revue de code ]. Il est vrai que les options fournies par le préprocesseur gnu sont un peu confuses. Cependant, la suppression de tous les répertoires de la cible de construction avec -MM
est documenté et n'est pas un bug [ gpp ] :
Par défaut, CPP prend le nom du fichier d'entrée principal, supprime tout composants de l'annuaire et tout suffixe de fichier tel que '.c', et ajoute le suffixe d'objet habituel de la le suffixe d'objet habituel de la plate-forme.
Le (un peu plus récent) -MMD
est probablement ce que vous voulez. Pour être complet, voici un exemple de fichier makefile qui supporte plusieurs répertoires src et répertoires de compilation avec quelques commentaires. Pour une version simple sans répertoire de compilation, voir [ revue de code ].
CXX = clang++
CXX_FLAGS = -Wfatal-errors -Wall -Wextra -Wpedantic -Wconversion -Wshadow
# Final binary
BIN = mybin
# Put all auto generated stuff to this build dir.
BUILD_DIR = ./build
# List of all .cpp source files.
CPP = main.cpp $(wildcard dir1/*.cpp) $(wildcard dir2/*.cpp)
# All .o files go to build dir.
OBJ = $(CPP:%.cpp=$(BUILD_DIR)/%.o)
# Gcc/Clang will create these .d files containing dependencies.
DEP = $(OBJ:%.o=%.d)
# Default target named after the binary.
$(BIN) : $(BUILD_DIR)/$(BIN)
# Actual target of the binary - depends on all .o files.
$(BUILD_DIR)/$(BIN) : $(OBJ)
# Create build directories - same structure as sources.
mkdir -p $(@D)
# Just link all the object files.
$(CXX) $(CXX_FLAGS) $^ -o $@
# Include all .d files
-include $(DEP)
# Build target for every single object file.
# The potential dependency on header files is covered
# by calling `-include $(DEP)`.
$(BUILD_DIR)/%.o : %.cpp
mkdir -p $(@D)
# The -MMD flags additionaly creates a .d file with
# the same name as the .o file.
$(CXX) $(CXX_FLAGS) -MMD -c $< -o $@
.PHONY : clean
clean :
# This should remove all generated files.
-rm $(BUILD_DIR)/$(BIN) $(OBJ) $(DEP)
Cette méthode fonctionne car s'il existe plusieurs lignes de dépendance pour une seule cible, les dépendances sont simplement jointes, par ex :
a.o: a.h
a.o: a.c
./cmd
est équivalent à :
a.o: a.c a.h
./cmd
comme mentionné à : Makefile plusieurs lignes de dépendance pour une seule cible ?
0 votes
Après avoir écrit ma réponse ci-dessous, j'ai regardé dans la liste connexe et j'ai trouvé : stackoverflow.com/questions/297514/ qui semble être un duplicata. La réponse de Chris Dodd est équivalente à la mienne, bien qu'elle utilise une convention de dénomination différente.