Au travail, nous utilisons un makefile commun que d'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 de pouvoir supprimer certains fichiers spécifiques, mais si j'ajoute une cible propre dans mon makefile, elle remplace simplement l'ancienne.
Je sais que je peux simplement créer une nouvelle cible avec un nouveau nom et le faire appeler clean, puis faire d'autres choses, mais pour des raisons de cohérence, j'aimerais pouvoir simplement appeler make clean et lui faire tout faire.
Est-ce possible?
Vous pouvez écrire votre propre nettoyage et en faire un pré-requis du nettoyage commun.
clean: myclean myclean: rm quel que soit
Le vôtre courra en premier. Si, pour une raison quelconque, vous souhaitez que le nettoyage commun s'exécute en premier, la solution sera plus compliquée.
MODIFIER:
Voici la meilleure solution que je puisse voir qui exécute la règle commune avant la règle locale:
include Makefile.common
clean:
$(MAKE) -f Makefile.common $@
rm whatever additional things
La directive include
est nécessaire car le makefile local s'appuie sur le commun pour d'autres choses que clean
. La règle locale clean
remplace la règle commune clean
, mais invoque la règle commune clean
avant d'effectuer le travail supplémentaire. (Ce dépassement entraînera certains avertissements, ce qui est une nuisance; je ne connais pas un bon moyen de les faire taire.)
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 un seul!
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" de la règle propre:
% make clean
rm -f *.o
rm -f *.h.gen
C'est simple à mettre en place et ça compose assez bien je pense. Notez que spécifiquement parce qu'il s'agit d'une règle à deux points, vous n'obtenez pas les erreurs "commandes prioritaires" que vous obtenez normalement lorsque vous définissez deux règles pour la même cible. C'est en quelque sorte l'intérêt des règles du double-colon.
Il semble que la règle commune du makefile 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 œil à règles du double-point , mais celles-ci introduisent un tout autre ensemble de problèmes à considérer.
Utilisez des règles implicites:
existing-target: my-extention
my-extention:
echo running command 1
echo running command 2
Tutoriel très simple pour monter en puissance.
Lorsque vous utilisez :: , vous pouvez rencontrer des problèmes car make se plaint lorsque vous mélangez des deux-points : et les deux points :: règles:
a:
echo a
a::
echo aa
aura pour résultat:
. . .
*** target file `a' has both : and :: entries. Stop.
Ajout d'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 makefile local avec tous les éléments spécifiques 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 marqué pour 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 le makefile local 1, il s'exécute
rm -f *.dep *.o *.a MyExe1 MyExe2
Et si nous courons make clean
pour le makefile local 2, il s'exécute
rm -f *.dep *.o *.a MyExe3 MyExe4
Pour la nôtre, nous définissons une variable, EXTRAFILESTOCLEAN, puis lorsque la règle de nettoyage 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 provoquer des problèmes inattendus si vous définissez cette variable sur des valeurs étranges, mais vous pouvez vous prémunir contre celles-ci en ajoutant des préfixes ou d'autres tests.