2010-07-16 7 views
58

J'ai structuré quelque chose comme makefile ceci:makefile exécuter une autre cible

all : 
    compile executable 

clean : 
    rm -f *.o $(EXEC) 

j'ai réalisé que je courais toujours « make clean » suivi de « clair » dans mon terminal avant de lancer « faire tout ». J'aime avoir un terminal propre avant d'essayer de passer au crible les erreurs de compilation C++. J'ai donc essayé d'ajouter une troisième cible:

fresh : 
    rm -f *.o $(EXEC) 
    clear 
    make all 

Cela fonctionne, mais cela exécute une deuxième instance de make (je crois). Existe-t-il un bon moyen d'obtenir la même fonctionnalité sans exécuter une 2ème instance de make? En fait

Répondre

96

vous avez raison: il court une autre instance de faire. Une solution possible serait:

.PHONY : clearscr fresh clean all 

all : 
    compile executable 

clean : 
    rm -f *.o $(EXEC) 

fresh : clean clearscr all 

clearscr: 
    clear 

En appelant make fresh vous obtenez d'abord la cible clean, le clearscreen qui court clear et enfin all qui fait le travail.

EDIT

Que se passe dans le cas de constructions parallèles avec l'option de faire -j? Il y a un moyen de réparer la commande. Le manuel de la marque, la section 4.2:

De temps en temps, cependant, vous avez une situation où vous voulez imposer un ordre spécifique sur les règles à invoquer sans forcer la cible à être mis à jour si l'une de ces règles est exécuté . Dans ce cas, vous souhaitez définir des prérequis pour la commande uniquement. Les conditions préalables à la commande peuvent être spécifiées en plaçant un symbole de tuyau (|) dans la liste des prérequis: toutes les conditions préalables à gauche du symbole de tuyau sont normales; les prérequis à droite sont uniquement sur commande: cibles: normal-pre-requis | Conditions préalables à la commande

La section des prérequis normaux peut bien sûr être vide. En outre, vous pouvez toujours déclarer plusieurs lignes de prérequis pour la même cible: elles sont ajoutées de manière appropriée. Notez que si vous déclarez le même fichier à la fois normal et l'ordre que condition sine qua non, la condition normale est prioritaire (car ils sont un surensemble strict du comportement d'une condition sine qua non de la commande uniquement).

D'où le makefile devient

.PHONY : clearscr fresh clean all 

all : 
    compile executable 

clean : 
    rm -f *.o $(EXEC) 

fresh : | clean clearscr all 

clearscr: 
    clear 
+1

@ sas4740.: fondamentalement tout suit '.PHONY:' est traité comme un mot-clé qui est toujours exécuté, alors que les cibles non-fausses sont destinées à être des fichiers. – Dacav

+0

sont des "Conditions préalables à la commande" conditionnelles? pour la cible t2 Je veux d'abord faire t0, que seulement si t0 réussit t1, et seulement si les deux réussissent une tâche en t3 – fantastory

+1

@fantastory, non, je ** pense ** qu'ils sont indépendants. 't2' dépendra de' t0', 't1' et' t3'. Si vous en avez besoin, vous devez mettre 't3' comme requis par' t2', 't1' comme requis par' t3' et 't0' comme requis par' t1'. Cela signifie 3 règles différentes. Vous devriez vérifier ceci, cependant. Je ne suis pas sûr à 100%. – Dacav

-11

À invite de commande linux: & clair font

+0

Je pense que vous vouliez dire « make clean && make clear » mais cela ne suffit pas à l'inefficacité de la charge faire une seconde fois –

+7

peut vous rendre plus clair :) – fantastory

+3

@fantastory: essayez avec 'make clear | plus' – Dacav

0

Si vous avez supprimé la ligne make all de votre cible "frais":

fresh : 
    rm -f *.o $(EXEC) 
    clear 

Vous pouvez simplement exécuter la commande make fresh all, qui s'exécutera sous la forme make fresh; make all.

Certains pourraient considérer cela comme une deuxième instance de faire, mais il est certainement pas un sous-instance de faire (une marque à l'intérieur d'une marque), qui est ce que votre tentative semblait entraîner

Questions connexes