Dans sa réponse @Grundlefleck explique comment vérifier si un répertoire existe ou non. J'en ai essayé d'utiliser ceci dans un makefile
comme suit:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
Fonctionnement make foo.bak
(étant donné que foo.bar
existe) génère l'erreur suivante:
echo "foo"
foo
if [ -d "~/Dropbox" ]; then
/bin/sh: -c: line 1: syntax error: unexpected end of file
make: *** [foo.bak] Error 2
La solution de contournement que j'ai faite était d'avoir un script bash autonome dans lequel le test est implémenté et j'ai appelé le script à partir de makefile
. Cela semble toutefois très lourd. Existe-t-il un moyen plus agréable de vérifier si un répertoire existe à l'intérieur de makefile
?
Les commandes Make, si une commande Shell, doivent être sur une seule ligne ou sur plusieurs lignes à l'aide d'une barre oblique inverse pour l'extension de ligne. Donc, cette approche fonctionnera:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then echo "Dir exists"; fi
Ou
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then \
echo "Dir exists"; \
fi
Cette approche fonctionne avec des échos minimaux:
.PHONY: all
all:
ifneq ($(wildcard ~/Dropbox/.*),)
@echo "Found ~/Dropbox."
else
@echo "Did not find ~/Dropbox."
endif
Agit en l'absence d'un répertoire
Si vous avez seulement besoin de savoir si un répertoire n'existe pas et si vous voulez agir sur celui-ci en le créant par exemple, vous pouvez utiliser des cibles Makefile ordinaires:
directory = ~/Dropbox
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) does not exist"
mkdir -p $@
.PHONY: all
Remarques:
|
indique que make ne devrait pas se soucier de l’horodatage (c’est un order-only-prerequisite ).mkdir -p $@
, vous pouvez écrire false
pour quitter ou résoudre votre cas différemment.Si vous devez également exécuter une série d'instructions particulière sur l'existence d'un répertoire, vous ne pouvez pas utiliser ce qui précède. En d'autres termes, cela équivaut à:
if [ ! -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does not exist"
fi
Il n'y a pas d'instruction else
.
Agir en présence d'un répertoire
Si vous voulez l'inverse de if-statement, c'est également possible:
directory = $(wildcard ~/Dropbox)
all: | $(directory)
@echo "Continuation regardless of existence of ~/Dropbox"
$(directory):
@echo "Folder $(directory) exists"
.PHONY: all $(directory)
Ceci est équivalent à:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
fi
Encore une fois, il n'y a pas d'instruction else
.
Agir à la fois sur la présence et sur l'absence d'un répertoire
Cela devient un peu plus lourd, mais vous donne finalement des objectifs intéressants pour les deux cas:
directory = ~/Dropbox
dir_target = $(directory)-$(wildcard $(directory))
dir_present = $(directory)-$(directory)
dir_absent = $(directory)-
all: | $(dir_target)
@echo "Continuation regardless of existence of ~/Dropbox"
$(dir_present):
@echo "Folder $(directory) exists"
$(dir_absent):
@echo "Folder $(directory) does not exist"
.PHONY: all
Ceci est équivalent à:
if [ -d "~/Dropbox" ]; then
echo "The ~/Dropbox folder does exist"
else
echo "The ~/Dropbox folder does not exist"
fi
Naturellement, le développement de caractère générique peut être plus lent qu'une instruction if-else. Cependant, le troisième cas est probablement assez rare et est simplement ajouté à des fins de complétude.
Essaye ça:
.PHONY: all
something:
echo "hi"
all:
test -d "Documents" && something
Cela n'exécutera les commandes sous something
que si Documents
existe.
Afin de traiter le problème noté dans les commentaires, vous pouvez créer une variable comme celle-ci:
PATH_TEST = ~/SomeDirectory
test -d $(PATH_TEST) && something
J'ai eu un cas où je voulais définir une variable basée sur le test si un répertoire existe ou non au plus haut niveau du Makefile
où les approches décrites ci-dessus ne fonctionnent pas. J'ai trouvé ici une belle solution qui peut être utilisée comme ceci:
MY_DIRNAME=../External
ifneq "$(wildcard $(MY_DIRNAME) )" ""
# if directory MY_DIRNAME exists:
INCLUDES += -I../External
else
# if it doesn't:
INCLUDES += -I$(HOME)/Code/External
endif
Cela modifiera la variable INCLUDES
en fonction du répertoire stocké dans MY_DIRNAME
existe ou pas.
(Motivation: Dans mon cas, cette variable serait utilisée dans un autre Makefile
inclus ultérieurement par le premier:
include $(SFRAME_DIR)/Makefile.common
Je voulais que le même Makefile
travaille dans deux environnements différents de manière simple.)
Il existe une réponse très différente qui vous permet d’utiliser vos instructions if
telles que vous les avez envisagées dans un shell:
.ONESHELL:
foo.bak: foo.bar
echo "foo"
if [ -d "~/Dropbox" ]; then
echo "Dir exists"
fi
Notez que la seule différence est ONESHELL cible spéciale .