web-dev-qa-db-fra.com

Comment vérifier si le fichier existe dans le fichier Makefile pour pouvoir le supprimer?

Dans la section nettoyage de ma Makefile, j'essaie de vérifier si le fichier existe avant de le supprimer définitivement. J'utilise ce code mais je reçois des erreurs.

Qu'est ce qui ne va pas avec ça?

 if [ -a myApp ]
 then
     rm myApp
 fi

Je reçois ce message d'erreur

 if [ -a myApp ]
 /bin/sh: Syntax error: end of file unexpected (expecting "then")
 make: *** [clean] Error 2
111

La deuxième réponse en haut mentionne ifeq, mais ne mentionne pas que ceux-ci doivent être au même niveau que le nom de la cible, par exemple, pour télécharger un fichier uniquement s'il n'existe pas, le code suivant peut être utilisé:

if fi
download:
ifeq (,$(wildcard ./glob.c))
    curl … -o glob.c
endif
14
cnst

Il est étrange de voir autant de personnes utiliser les scripts Shell pour cela. Je cherchais un moyen d'utiliser la syntaxe native du makefile, car je l'écris en dehors de toute cible. Vous pouvez utiliser la fonction wildcard pour vérifier si le fichier existe:

 ifeq ($(UNAME),Darwin)
     Shell := /opt/local/bin/bash
     OS_X  := true
 else ifneq (,$(wildcard /etc/redhat-release))
     OS_RHEL := true
 else
     OS_DEB  := true
     Shell := /bin/bash
 endif 

Mettre à jour:

J'ai trouvé un moyen qui fonctionne vraiment pour moi:

ifneq ("$(wildcard $(PATH_TO_FILE))","")
    FILE_EXISTS = 1
else
    FILE_EXISTS = 0
endif
173
holms

Il faudra peut-être une barre oblique inverse à la fin de la ligne pour continuer (même si cela dépend peut-être de la version de make):

if [ -a myApp ] ; \
then \
     rm myApp ; \
fi;
48
Mark Wilkins

Le problème est que vous divisez votre commande sur plusieurs lignes. Ainsi, vous pouvez soit utiliser le \ à la fin des lignes pour continuer comme ci-dessus, soit vous pouvez tout obtenir sur une ligne avec l'opérateur && dans bash. 

Ensuite, vous pouvez utiliser une commande test pour vérifier si le fichier existe, par exemple:

test -f myApp && echo File does exist

-f file Vrai si le fichier existe et est un fichier normal.

-s file True si le fichier existe et que sa taille est supérieure à zéro.

ou ne pas:

test -f myApp || echo File does not exist
test ! -f myApp && echo File does not exist

La test est équivalente à la commande [

[ -f myApp ] && rm myApp   # remove myApp if it exists

et cela fonctionnerait comme dans votre exemple original.

Voir: help [ ou help test pour plus de syntaxe.

39
kenorb

Ou simplement le mettre sur une seule ligne, comme make l'aime bien:

if [ -a myApp ]; then rm myApp; fi;
22
Jeroen

Manquer un point-virgule

if [ -a myApp ];
then
  rm myApp
fi

Cependant, je suppose que vous vérifiez l'existence avant la suppression afin d'éviter un message d'erreur. Si tel est le cas, vous pouvez simplement utiliser rm -f myApp qui "force" la suppression, c’est-à-dire que le fichier n’existe pas.

12
drysdam
FILE1 = /usr/bin/Perl
FILE2 = /nofile

ifeq ($(Shell test -e $(FILE1) && echo -n yes),yes)
    RESULT1=$(FILE1) exists.
else
    RESULT1=$(FILE1) does not exist.
endif

ifeq ($(Shell test -e $(FILE2) && echo -n yes),yes)
    RESULT2=$(FILE2) exists.
else
    RESULT2=$(FILE2) does not exist.
endif

all:
    @echo $(RESULT1)
    @echo $(RESULT2)

résultats d'exécution:

bash> make
/usr/bin/Perl exists.
/nofile does not exist.
8
Robin Hsu

Une solution en ligne:

   [ -f ./myfile ] && echo exists

Solution à une ligne avec action d'erreur:

   [ -f ./myfile ] && echo exists || echo not exists

Exemple utilisé dans mes directives make clean:

clean:
    @[ -f ./myfile ] && rm myfile || true

Et make clean fonctionne toujours sans aucun message d'erreur!

4
Antonio Feitosa
test ! -f README.md || echo 'Support OpenSource!' >> README.md

"Si README.md n'existe pas, ne faites rien (et quittez avec succès). Sinon, ajoutez du texte à la fin."

Si vous utilisez && au lieu de ||, vous générez une erreur lorsque le fichier n'existe pas:

Makefile:42: recipe for target 'dostuff' failed
make: *** [dostuff] Error 1
0
Matt Janssen

Les réponses ressemblent à celle de @ mark-wilkins en utilisant\pour continuer les lignes et; les terminer dans le shell ou comme ceux de @kenorb le changer en une seule ligne est une bonne chose et résoudra ce problème. 

il existe une réponse plus simple au problème initial (comme l'a souligné @ alexey-polonsky). Utilisez l'indicateur -f pour rm afin qu'il ne déclenche pas d'erreur 

rm -f myApp

c'est plus simple, plus rapide et plus fiable. Faites juste attention à ne pas vous retrouver avec une barre oblique et une variable vide

rm -f/$ (myAppPath) # NE JAMAIS FAIRE

vous pourriez finir par supprimer votre système.

0
Michael