Remplacer la cible dans makefile pour ajouter plus de commandes?

Au travail, nous utilisons un makefile commun que les autres makefiles incluent (via l'instruction include) et il a une cible Générique "propre" qui tue certains fichiers communs. Je veux ajouter à cette cible dans mon nouveau makefile afin que je puisse supprimer certains fichiers spécifiques, mais si j'ajoute une cible propre dans mon makefile, elle remplace simplement l'ancien.

Je sais que je peux juste faire une nouvelle cible avec un nouveau nom et l'appeler propre, puis faire d'autres choses, mais par souci de cohérence, j'aimerais pouvoir juste appelez make clean et demandez-lui de tout faire.

Est-ce possible?

32
demandé sur Paul D. 2009-10-29 19:24:14

6 réponses

Vous pouvez écrire votre propre propre propre et en faire une préq du propre commun.

clean: myclean

myclean:
    rm whatever

Le vôtre courra en premier. Si pour une raison quelconque vous voulez que le nettoyage commun s'exécute en premier, la solution sera plus compliquée.

28
répondu Beta 2009-10-29 16:52:07

J'ai vu cela dans plusieurs magasins. L'approche la plus courante consiste à utiliser des règles à deux points, en supposant que vous utilisez quelque chose comme GNU make. Dans votre makefile commun, vous auriez quelque chose comme ceci:

clean::
        # standard cleanup, like remove all .o's:
        rm -f *.o

Notez qu'il y a deux deux points après clean, pas seulement un!

Dans votre autre makefile, vous déclarez simplement clean à nouveau, en tant que règle à deux points:

clean::
        # custom cleanup, like remove my special generated files:
        rm -f *.h.gen

Lorsque vous invoquez make clean, GNU make exécutera automatiquement ces deux "branches" du règle propre:

% make clean
rm -f *.o
rm -f *.h.gen

Il est simple à mettre en place et il compose assez soigneusement je pense. Notez que spécifiquement parce qu'il s'agit d'une règle à deux points, vous n'obtenez pas les erreurs "overriding commands" que vous obtenez normalement lorsque vous définissez deux règles pour la même cible. C'est en quelque sorte le point des règles du double-côlon.

55
répondu Eric Melski 2012-07-23 21:49:40

Il semble que la règle de makefile commune devrait être appelée quelque chose comme common-clean. Ensuite, chaque makefile principal déclarerait sa règle propre comme

clean: common-clean

Et vous êtes prêt.

Si ce n'est pas une option, vous pouvez jeter un oeil à règles à deux points, mais celles-ci introduisent un tout autre ensemble de problèmes à considérer.

5
répondu jamessan 2009-10-29 16:36:12

Utiliser des règles implicites:

existing-target: my-extention

my-extention:
    echo running command 1
    echo running command 2

Très simple faire tutoriel pour monter en puissance.

Lors de l'utilisation de :: vous pouvez rencontrer des problèmes depuis que faire se plaint quand on mélange unique du côlon : et deux points :: règles:

a:
    echo a

a::
    echo aa

Donnera:

. . .
*** target file `a' has both : and :: entries.  Stop.
4
répondu Bohdan 2014-05-15 23:58:30

Pour la nôtre, nous définissons une variable, EXTRAFILESTOCLEAN, puis lorsque la règle clean s'exécute, elle a une étape pour supprimer tout ce qui est spécifié dans la variable EXTRAFILESTOCLEAN

clean:
    rm -f *.o
ifdef $(EXTRAFILESTOCLEAN)
    rm -f $(EXTRAFILESTOCLEAN)
endif

Cela peut causer des problèmes inattendus si vous définissez cette variable sur des valeurs étranges, mais vous pouvez vous en prémunir en ajoutant des préfixes ou d'autres tests.

1
répondu davenpcj 2013-08-09 01:27:12

Ajouter une autre solution possible que j'ai vue pour la postérité... Je sais que L'OP se méfiait de changer le makefile commun, mais quelque chose comme ça fonctionne et implique des changements minimes.

Makefile Local 1:

CLEAN=MyExe1 MyExe2
....
include /my/common/makefile

Makefile Local 2:

CLEAN=MyExe3 MyExe4
....
include /my/common/makefile

Makefile commun:

clean:
     rm -f *.dep *.o *.a $(CLEAN)

, Fondamentalement, l'idée est de définir une variable (dans ce cas - CLEAN) dans chaque local makefile avec tous les éléments que vous souhaitez supprimer. Ensuite, le makefile commun s'exécute rm -f sur tous les types de fichiers communs à supprimer, plus Tout ce qui a été spécifiquement signalé pour la suppression dans chaque makefile local via la variable CLEAN. S'il n'y a rien de spécifique à supprimer, omettez simplement la déclaration de variable ou laissez-la Vide (CLEAN=)

Alors maintenant, si nous exécutons make clean pour Makefile local 1, il exécute

rm -f *.dep *.o *.a MyExe1 MyExe2

Et si nous exécutons make clean pour Makefile local 2, il exécute

rm -f *.dep *.o *.a MyExe3 MyExe4
1
répondu yano 2017-03-20 18:26:50