J'ai un makefile qui construit puis appelle un autre makefile. Puisque ce makefile appelle plus de makefiles qui font le travail, il ne change pas vraiment. Ainsi, il continue de penser que le projet est construit et à jour.
dnetdev11 ~ # make
make: `release' is up to date.
Comment forcer le makefile à reconstruire la cible?
clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean
build = svn up ~/xxx \
$(clean) \
~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace \
$(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1) \
release:
$(build )
debug:
$(build DEBUG=1)
clean:
$(clean)
install:
cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib
Remarque: les noms ont été supprimés pour protéger les innocents
Edit: Version finale fixe:
clean = $(MAKE) -f xxx_compile.workspace.mak clean;
build = svn up; \
$(clean) \
./cbp2mak/cbp2mak -C . xxx_compile.workspace; \
$(MAKE) -f xxx_compile.workspace.mak $(1); \
.PHONY: release debug clean install
release:
$(call build,)
debug:
$(call build,DEBUG=1)
clean:
$(clean)
install:
cp ./source/xxx_utillity/release/xxx_util /usr/bin
cp ./dlls/Release/xxxcore.so /usr/lib
.PHONY
n'était pas votre seul problème, et vous n'êtes pas vraiment censé modifier la solution dans la question, ou du moins plus maintenant.)Réponses:
Vous pouvez déclarer qu'une ou plusieurs de vos cibles sont fausses .
la source
:
, pas seulement au résultat final que vous voulez créer (par exemple votre fichier binaire). Dans la question,release
,debug
,clean
etinstall
sont les cibles, et non Makexxx_util
ouxxxcore.so
ou quoi que ce soit d' autre.Le
-B
commutateur à faire, dont la forme longue est--always-make
, indiquemake
de ne pas tenir compte des horodatages et de créer les cibles spécifiées. Cela peut aller à l'encontre de l'objectif de l'utilisation de make, mais c'est peut-être ce dont vous avez besoin.la source
.PHONY
pourrait être plus pratique.Une astuce qui était autrefois documentée dans un manuel Sun pour
make
est d'utiliser une cible (inexistante) '.FORCE'. Vous pouvez le faire en créant un fichier, force.mk, qui contient:Ensuite, en supposant que votre makefile existant est appelé
makefile
, vous pouvez exécuter:Puisqu'il
.FORCE
n'existe pas, tout ce qui en dépend sera obsolète et reconstruit.Tout cela fonctionnera avec n'importe quelle version de
make
; sous Linux, vous avez GNU Make et pouvez donc utiliser la cible .PHONY comme indiqué.Il convient également
make
de se demander pourquoi la publication est à jour. Cela peut être dû au fait que vous avez unetouch release
commande parmi les commandes exécutées; cela peut être dû au fait qu'il existe un fichier ou un répertoire appelé «release» qui existe et qui n'a pas de dépendances et qui est donc à jour. Ensuite, il y a la vraie raison ...la source
Quelqu'un d'autre a suggéré .PHONY, ce qui est tout à fait correct. .PHONY doit être utilisé pour toute règle pour laquelle une comparaison de date entre l'entrée et la sortie n'est pas valide. Puisque vous n'avez aucune cible du formulaire,
output: input
vous devez utiliser .PHONY pour TOUS!Cela dit, vous devriez probablement définir quelques variables en haut de votre makefile pour les différents noms de fichiers, et définir de vraies règles make qui ont à la fois des sections d'entrée et de sortie afin que vous puissiez utiliser les avantages de make, à savoir que vous ne compilerez réellement les choses qui sont nécessaires pour faire face!
Edit: exemple ajouté. Non testé, mais voici comment vous faites .PHONY
la source
.PHONY
cible n'a pas d'importance. Cela peut être n'importe où dans leMakefile
.Cette technique simple permettra au makefile de fonctionner normalement lorsque le forçage n'est pas souhaité. Créez une nouvelle cible appelée force à la fin de votre makefile . La cible de force touchera un fichier dont dépend votre cible par défaut. Dans l'exemple ci-dessous, j'ai ajouté touch myprogram.cpp . J'ai également ajouté un appel récursif à faire . Cela entraînera la création de la cible par défaut à chaque fois que vous tapez make force .
la source
make
dans un Makefile. Utilisez$(MAKE)
plutôt.Si je me souviens bien, «make» utilise des horodatages (heure de modification du fichier) pour déterminer si une cible est à jour ou non. Une manière courante de forcer une reconstruction est de mettre à jour cet horodatage à l'aide de la commande «touch». Vous pouvez essayer d'appeler 'touch' dans votre makefile pour mettre à jour l'horodatage de l'une des cibles (peut-être l'un de ces sous-makefiles), ce qui pourrait forcer Make à exécuter cette commande.
la source
J'ai essayé ça et ça a marché pour moi
ajoutez ces lignes à Makefile
enregistrer et appeler maintenant
et il recompilera tout à nouveau
Qu'est-il arrivé?
1) «nouveaux» appels propres. «clean» fait «rm» qui supprime tous les fichiers objets qui ont l'extension «.o».
2) «nouveaux» appels «faire». 'faire' voir qu'il n'y a pas de fichiers '.o', donc il crée à nouveau tous les '.o'. puis l'éditeur de liens relie tout le fichier .o à une sortie exécutable
Bonne chance
la source
new
meilleur usage$(MAKE)
quemake
Selon Miller's Recursive Make Considered Harmful, vous devriez éviter d'appeler
$(MAKE)
! Dans le cas que vous montrez, c'est inoffensif, car ce n'est pas vraiment un makefile, juste un script wrapper, qui aurait tout aussi bien pu être écrit dans Shell. Mais vous dites que vous continuez comme ça à des niveaux de récursion plus profonds, donc vous avez probablement rencontré les problèmes indiqués dans cet essai révélateur.Bien sûr, avec GNU, c'est difficile à éviter. Et même s'ils sont conscients de ce problème, c'est leur façon documentée de faire les choses.
OTOH , makepp été créé pour résoudre ce problème. Vous pouvez écrire vos makefiles au niveau de chaque répertoire, mais ils sont tous rassemblés dans une vue complète de votre projet.
Mais les makefiles hérités sont écrits de manière récursive. Il existe donc une solution de contournement où
$(MAKE)
ne fait rien d'autre que canaliser les sous-requêtes vers le processus makepp principal. Seulement si vous faites des choses redondantes ou, pire, contradictoires entre vos soumissions, vous devez demander--traditional-recursive-make
(ce qui brise bien sûr cet avantage de makepp). Je ne connais pas vos autres makefiles, mais s'ils sont écrits proprement, avec makepp, les reconstructions nécessaires devraient se produire automatiquement, sans avoir besoin de hacks suggérés ici par d'autres.la source
:
), il sera toujours reconstruit si nécessaire.Cela a déjà été mentionné, mais je pensais pouvoir ajouter à l'utilisation
touch
Si vous avez
touch
tous les fichiers source à compiler, latouch
commande modifie les horodatages d'un fichier à l'heure système à laquelle latouch
commande a été exécutée.L'horodatage du fichier source est ce qui permet
make
de "savoir" qu'un fichier a changé et doit être recompiléPar exemple: si le projet était un projet C ++, alors faites
touch *.cpp
, puis réexécutezmake
et make devrait recompiler l'ensemble du projet.la source
Si vous n'avez pas besoin de conserver l'une des sorties que vous avez déjà compilées avec succès
reconstruit tout
la source
Cela dépend en fait de la cible. S'il s'agit d'une cible bidon (c'est-à-dire que la cible n'est PAS liée à un fichier), vous devez la déclarer comme .PHONY.
Si toutefois la cible n'est pas une cible bidon mais que vous voulez simplement la reconstruire pour une raison quelconque (un exemple est lorsque vous utilisez la macro de prétraitement __TIME__), vous devez utiliser le schéma FORCE décrit dans les réponses ici.
la source
http://www.gnu.org/software/make/manual/html_node/Force-Targets.html#Force-Targets
la source
Comme l'a souligné Abernier, il existe une solution recommandée dans le manuel GNU make, qui utilise une `` fausse '' cible pour forcer la reconstruction d'une cible:
Cela fonctionnera propre, quelles que soient les autres dépendances.
J'ai ajouté le point-virgule à la solution du manuel, sinon une ligne vide est requise.
la source
Sur mon système Linux (Centos 6.2), il y a une différence significative entre déclarer la cible .PHONY et créer une fausse dépendance sur FORCE, lorsque la règle crée en fait un fichier correspondant à la cible. Lorsque le fichier doit être régénéré à chaque fois, il a fallu à la fois la fausse dépendance FORCE sur le fichier et .PHONY pour la fausse dépendance.
faux:
droite:
la source
make clean
supprime tous les fichiers objets déjà compilés.la source