2009-10-16 3 views
1

Je sais que je le fais mal, mais je n'arrive pas à comprendre comment organiser ce makefile. Je définis mes fichiers source util, et utiliser certaines fonctions pour définir les fichiers .o d'eux ici:Dans un makefile, comment j'exécute une commande sur chaque nom de fichier dans une variable?

UTIL_SRC = utils/src/foo.cpp utils/src/bar.cpp utils/src/baz.cpp 

UTIL_OBJS = $(patsubst utils/src/%.cpp,utils/obj/%.o,$(UTIL_SRC)) 

Ceci est la cible que j'utilise ces fichiers pour:

lib : lib/libutils.a 

lib/libutils.a : $(UTIL_OBJS) 
    rm -f lib/libutils.a 
    ar -c -q lib/libutils.a $(UTIL_OBJS) 

Puis, quand je aller à la règle pour compiler ces bébés, j'aimerais juste avoir une commande qui parcourrait chaque fichier UTIL_OBJS et chaque fichier UTIL_SRC. Au lieu de cela, j'ai recouru à cette monstruosité, qui va à l'encontre du but de les stocker dans des variables.

$(UTIL_OBJS) : $(UTIL_SRC) 
    g++ $(UTIL_FLAGS) utils/src/foo.cpp -o utils/obj/foo.o 
    g++ $(UTIL_FLAGS) utils/src/bar.cpp -o utils/obj/bar.o 
    g++ $(UTIL_FLAGS) utils/src/baz.cpp -o utils/obj/baz.o 

Puis-je condenser ceci en une ligne? Comment? Merci, super!

Répondre

8

Il est généralement plus facile travailler avec des règles implicites. Il y en a beaucoup de prédéfinis, où vous n'aurez qu'à spécifier des variables.

CXX=g++ 
CXXFLAGS=$(UTIL_FLAGS) 

Ensuite, vous devez définir un fichier exécutable, comme celui-ci

myutil: $(UTIL_OBJS) 

Puisque vous n'êtes pas stocker vos objets dans le même répertoire, vous devez spécifier une nouvelle règle implicite, ainsi que (sinon, nous aurions fini maintenant)

utils/obj/%.o: utils/obj/%.cpp 

% est un modèle match, il va correspondre au même texte sur les deux côtés gauche et à droite, de sorte que cette règle fera foo.o sur foo.cpp. Essayez si cela va marcher sans la commande (il aurait peut-être saisi que d'une autre règle, je ne suis pas sûr), sinon laissez-le dire:

utils/obj/%.o: utils/obj/%.cpp 
    $(CXX) $(CXXFLAGS) -o [email protected] $^ 

@ $ est l 'objectif de la règle (par exemple toto .o), et $^est tous les fichiers sur le côté droit. J'écris cela de haut en bas, sans la possibilité de le tester, alors s'il vous plaît laissez-moi savoir comment il s'est avéré .. :)

Pour le rendre encore plus élégant, vous pouvez inclure un fichier de dépendance

include .depend 

Si vous utilisez GNU make, il va essayer de rendre le fichier .depend si elle ne peut pas trouver (avec la vieille école faire, vous devez créer vous-même d'abord, il peut être juste un mannequin cependant, si vous voulez le gérer à travers le makefile)

.depend: $(UTIL_SRC) 
    $(CXX) -MM -o [email protected] $^ 

T Le fichier de dépendances contiendra des lignes pour chaque fichier .cpp, indiquant les fichiers d'en-tête dont il a besoin, ce qui permettra à make de recompiler les fichiers nécessaires lorsque vous changez quelque chose. Cela n'aide pas avec votre question originale, juste pensé que cela pourrait être utile.

EDIT:
En réponse à votre modification.Vous pouvez également supprimer les commandes pour créer le fichier .a, qui est déjà disponible en tant que règle implicite. Je ne sais pas exactement comment cela fonctionne, je ne l'ai pas beaucoup utilisé. Je sais qu'il y a un tas de bizarreries pour gérer les fichiers .a (rchive?).

+0

En effet, les règles de modèle sont la voie à suivre. – Bernard

+0

J'ai essayé juste la règle de modèle sans la commande et cela n'a pas fonctionné. Cependant, en définissant explicitement la commande travaillée. Est-ce que la règle de pattern cause make pour chercher utils/src /%. Cpp? – jergason

+0

Non, il ne cherchera pas les fichiers .cpp, il regardera les utilitaires/obj /%. O les fichiers dont il a besoin, et cette règle va, donc ça va le faire depuis utils/src /%. Cpp. Cela fonctionne en quelque sorte à l'envers. Le déclencheur est la ligne 'myutil: $ (UTIL_OBJS)' où vous lui indiquez les fichiers .o que vous voulez. Et dans ce cas, tous sont dans utils/obj/ – falstro

0

Je pense que vous pouvez utiliser ceci: nouveau

$(UTIL_OBJS) : $(UTIL_SRC) 
    g++ $(UTIL_FLAGS) $(@ : .o = .cpp) -o [email protected] 

, je ne suis pas tout à fait sûr ... especialy sur les $ (@: Cpp = .o) partie

+4

Que signifient tous ces symboles magiques? Il ressemble à Perl sur le crack. – jergason

+0

$ @ est la cible de la règle,: lui dit de remplacer un suffixe – falstro