J'ai un petit projet qui construit un certain nombre de cibles à partir des mêmes fichiers source. Les cibles nécessitent la construction des fichiers sources avec différents drapeaux de compilation. C'est en fait sur cygwin donc je vais utiliser cela comme exemple concret bien que je suppose que c'est un problème générique.Comment faire pour s'assurer que les fichiers objet sont compilés avec les paramètres corrects dans Makefile avec plusieurs cibles MAKE
Donc, ce serait un Makefile exemple:
a: CFLAGS =
a: a.o c.o
b: CFLAGS = -mno-cygwin
b: b.o c.o
Cela fonctionne en principe, la construction d'une compilera avec unset CFLAGS et la construction b compilera avec CFLAGS mis à -mno-Cygwin. Mais seulement si c.o n'existe pas déjà.
Ce faisant
> make a b
dans un répertoire vierge d'abord compiler et a.c C.C en utilisant un CFLAGS vide. Ensuite, il va essayer de construire b en utilisant CFLAGS = -mno-cygwin. Mais comme c.o existe déjà, il ne recompilera pas c.c, ce qui se traduira par des erreurs de liens puisque les fichiers objets doivent avoir le même paramétrage de ce flag.
Encore une fois, le drapeau cygwin n'est qu'un exemple concret, et je cherche une solution générique.
Ce que j'ai essayé est d'introduire un objectif supplémentaire de vérifier les CFLAGS actuels et supprimer tous les fichiers d'objets si elle ne correspond pas à:
ARCH = `echo $(CFLAGS)`
checkTarget:
[email protected] test "`cat .arch`" != "$(ARCH)"; then \
rm *.o; \
/bin/echo -n $(ARCH) > .arch; \
fi
Insérer cet objectif comme une dépendance pour les deux cibles assure que tous les objets les fichiers sont recompilés si nécessaire.
a: CFLAGS =
a: checkTarget a.o c.o
b: CFLAGS = -mno-cygwin
b: checkTarget b.o c.o
Cette recompile cependant chaque fichier objet, ce qui est inutile, et devient un problème dans un projet plus vaste.
Y a-t-il une meilleure façon de procéder?
EDIT: Dans les commentaires à la réponse unique inclus un indice que vous pourriez faire les fichiers objet dépendent du contenu du CFLAGS. Je n'arrive pas à comprendre comment faire cela, sauf les transférer dans un fichier temporaire et les comparer aux précédents, puis les copier sur un fichier dépendant. N'y a-t-il pas de meilleur moyen?
Bonne réponse. Si le projet est volumineux, disons 50 fichiers objets, cela fonctionnera si le nombre de fichiers à recompiler (c.c dans l'exemple) est petit. Si la majorité exigeait une recompilation, cette stratégie deviendrait maladroite je pense. Des idées pour ce scénario? – thoni56
@ Thomas Nilsson: cela dépend de ce que vous essayez d'optimiser. Si vous ne voulez pas recompiler 'c.c' plus que nécessaire, vous devez en conserver différentes versions, et c'est le meilleur moyen. Si vous ne voulez pas garder plusieurs 'c.o', mais que vous voulez recompiler' c.o' seulement quand vous devez, il y a une autre façon, une légère amélioration sur votre checkTarget. Je vais modifier ma réponse pour l'inclure. – Beta
Hmmm, si je comprends bien, checkTarget est un horodatage de sorte que par exemple. Si vous construisez b mais que b.o et c.o existent, checkTarget déclenchera toujours la règle de construction. Ensuite, dans les commandes, vous êtes en train de câbler la construction de c.o selon le CFLAGS. Si c'est votre intention, je ne suis pas entièrement satisfait (mais encore une fois cela pourrait ne pas être possible ;-), parce que je devrais constamment mettre à jour les commandes de construction explicites lorsque mes exigences ont changé. J'espérais pouvoir faire en sorte que chaque% .o dépende des CFLAGS utilisés pour le compiler, et une compilation ne serait déclenchée que si le CFLAGS n'était pas le même. – thoni56