2012-05-04 3 views
2

je la configuration suivante pour mon C++ projet:makefile détection automatique des fichiers src et génération dépendance

dans le dossier src, il y a * Cpp et correspondant * .h et dans les dossiers Obj-I Je veux avoir mes fichiers .o. Jusqu'à présent, la compilation et la liaison ne posent pas de problème. Mais maintenant j'ai trop de fichiers .cpp et .h pour les mettre dans le Makefile manuellement. Je décide donc d'écrire cette petite instruction dans le makefile:

collect_sources: 
@echo "collecting source files"; 
@echo "SRCS = \\" > sources; 
@for file in ./src/*.cpp; \ 
do \ 
    echo "$$file \\" >> sources; \ 
done 

Je fais aussi

-include sources 

au début du makefile

Le fichier résultant sources semble bien, bien qu'il y ait backslash dans la dernière ligne que je n'aime pas. Mais ça devrait être dangereux aussi.

J'ai maintenant aussi besoin de créer automatiquement des dépendances. Dans ma dernière version dans laquelle je définissais les fichiers * .cpp-en SRCS directement dans le Makefile, le code suivant était bon:

$(SRCDIR)/%.cpp: 
    @$(CXX) $(DEPFLAGS) -MT \ 
    "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \ 
    $(addprefix ,$$file) >> $(DEP); 
clear_dependencies: 
    echo "" > $(DEP); 

depend: clear_dependencies $(SRCS) 

Mais avec notamment le sources -file, il ne parvient jamais au bloc de code supérieur.

Voici les constantes définies en haut du makefile:

CXX = g++ 
CXXFLAGS = -Wall \ 
     -Wextra \ 
     -Wuninitialized \ 
     -Wmissing-declarations \ 
     -pedantic \ 
     -O3 \ 
     -p -g -pg 
LDFLAGS = -p -g -pg 
DEPFLAGS = -MM 

SRCDIR = ./src 
OBJDIR = ./obj 

TARGET = ./bin/my_funky_function_which_is_not_the_real_name 

-include sources 

OBJSTMP = $(SRCS:.cpp=.o) 
OBJS  = $(OBJSTMP:$(SRCDIR)=$(OBJDIR)) 
DEP = depend.main 
EXT_SRC = .cpp 
EXT_OBJ = .o 

Qu'est-ce que je manque? Est-ce que mon approche est valide/faisable?

+0

sur une note de côté: s'il vous plaît ne suggérer aucun outil qui le fait déjà. Je veux vraiment comprendre cela et avoir un contrôle total sur ce qui se passe. – stefan

+0

Il y a une erreur simple et beaucoup d'amélioration possible. Jusqu'où veux-tu aller? – Beta

+0

étape par étape à l'optimum absolu ;-) – stefan

Répondre

7

Très bien, vous l'avez demandé.

1: Votre collect_sources:... include sources est un hackery glorieux de Rube Goldberg. Il suffit de faire ceci:

SRCS = $(wildcard ./src/*.cpp) 

Et si vous voulez le confirmer à l'oeil, vous pouvez le faire:

$(info $(SRCS)) 

2:

clear_dependencies: 
    echo "" > $(DEP); 

juste pour le plaisir de l'esthétique , réparons ça.

clear_dependencies: 
    $(RM) $(DEP); 

3:

$(SRCDIR)/%.cpp: 
    @$(CXX) $(DEPFLAGS) -MT \ 
    "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \ 
    $(addprefix ,$$file) >> $(DEP); 

Cela prendra un certain travail. D'abord le problème immédiat: la cible est un vrai fichier qui existe, et la règle n'a pas de prérequis. Par conséquent, la règle ne sera pas exécutée (je ne sais pas pourquoi cela a fonctionné pour vous dans une version précédente, peut-être que quelque chose d'autre était différent). En tant que solution temporaire, je suggère que nous passons à une règle de modèle statique et les cibles PHONY:

.PHONY:$(SRCS) 
$(SRCS) : $(SRCDIR)/%.cpp: 
    @$(CXX) $(DEPFLAGS) -MT \ 
    ... 

Voir si tout cela fonctionne, nous pouvons aborder les choses importantes.

+0

Tout d'abord, merci pour votre réponse. Je ne comprends pas ce que vous voulez dire par "la cible est un vrai fichier qui existe". vous avez raison de dire que ce n'était pas ce code à l'origine. au lieu du fichier $$ c'était quelque chose avec un @. – stefan

+0

@stefan, probablement '$ @'. En pratique, Make utilisera cette règle pour déterminer s'il faut reconstruire quelque chose comme './Src/foo.cpp'. Ce sera presque certainement un fichier qui existe déjà (à moins qu'il n'y ait plus à ce problème que vous nous l'avez dit). Donc, Make conclura que le fichier est à jour et n'a pas besoin d'être reconstruit. Même si/quand Make exécute la règle, je ne pense pas que le truc '$$ file' fonctionnera. – Beta

+0

vous avez absolument raison. et avec votre "PHONY" suggestion et "$ @" cela fonctionne bien :) – stefan

Questions connexes