Comment empêcher "l'erreur de répertoire existe déjà" dans un fichier Make quand on utilise mkdir

StackOverflow https://stackoverflow.com/questions/99132

  •  01-07-2019
  •  | 
  •  

Question

Je dois générer un répertoire dans mon fichier makefile et je ne souhaite pas que le " répertoire existe déjà avec une erreur " encore et encore, même si je peux facilement l'ignorer.

J'utilise principalement mingw / msys, mais j'aimerais quelque chose qui fonctionne aussi sur d'autres shells / systèmes.

J'ai essayé ça mais ça n'a pas marché, des idées?

ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
Était-ce utile?

La solution

Sous UNIX, utilisez simplement ceci:

mkdir -p $(OBJDIR)

L'option -p de mkdir empêche le message d'erreur si le répertoire existe.

Autres conseils

En regardant la documentation sur la marque officielle , voici un bon moyen de fais-le:

OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)

$(OBJDIR)/%.o : %.c
    $(COMPILE.c) $(OUTPUT_OPTION) <*>lt;

all: $(OBJS)

$(OBJS): | $(OBJDIR)

$(OBJDIR):
    mkdir -p $(OBJDIR)

Vous devriez voir ici l'utilisation de la | opérateur de pipe, définissant un ordre uniquement comme condition préalable. Cela signifie que la cible $ (OBJDIR) doit être existante (au lieu de plus récente ) afin de générer la cible actuelle.

Notez que j'ai utilisé mkdir -p . L'indicateur -p a été ajouté par rapport à l'exemple de la documentation. Voir les autres réponses pour une autre alternative.

Vous pouvez utiliser la commande de test:

test -d $(OBJDIR) || mkdir $(OBJDIR)

Voici une astuce que j'utilise avec GNU pour créer des répertoires de sortie du compilateur. Définissez d'abord cette règle:

  %/.d:
          mkdir -p $(@D)
          touch $@

Faites en sorte que tous les fichiers qui entrent dans le répertoire dépendent du fichier .d de ce répertoire:

 obj/%.o: %.c obj/.d
    $(CC) $(CFLAGS) -c -o $@ 
 .PRECIOUS: %/.d
lt;

Notez l'utilisation de $ < au lieu de $ ^.

Enfin, empêchez la suppression automatique des fichiers .d:

<*>

Sauter le fichier .d et dépendre directement du répertoire ne fonctionnera pas car l’heure de modification du répertoire est mise à jour chaque fois qu’un fichier est écrit dans ce répertoire, ce qui forcerait la reconstruction à chaque appel de make.

Si le répertoire existe déjà ne pose pas de problème, vous pouvez simplement rediriger stderr pour cette commande, en éliminant le message d'erreur suivant:

-mkdir $(OBJDIR) 2>/dev/null

Dans votre fichier Make:

target:
    if test -d dir; then echo "hello world!"; else mkdir dir; fi

Sous Windows

if not exist "$(OBJDIR)" mkdir $(OBJDIR)

Sous Unix | Linux

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
$(OBJDIR):
    mkdir $@

Ce qui fonctionne également pour plusieurs répertoires, par exemple ..

OBJDIRS := $(sort $(dir $(OBJECTS)))

$(OBJDIRS):
    mkdir $@

Ajouter $ (OBJDIR) en tant que première cible fonctionne bien.

Cela fonctionne sous mingw32 / msys / cygwin / linux

ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif

Si vous ignorez explicitement le code de retour et videz le flux d'erreur, votre marque ignorera l'erreur si elle se produit:

mkdir 2>/dev/null || true

Cela ne devrait pas causer de risque de course dans une fabrication parallèle - mais je ne l’ai pas testé pour en être sûr.

Un peu plus simple que la réponse de Lars:

something_needs_directory_xxx : xxx/..

et règle générique:

%/.. : ;@mkdir -p $(@D)

Pas de fichiers tactiles à nettoyer ou à créer .PRECIOUS: -)

Si vous voulez voir un autre petit truc générique gmake, ou si vous êtes intéressé par une fabrication non récursive avec un échafaudage minimal, vous voudrez peut-être consulter Deux autres astuces gmake bon marché et les autres publications relatives à la création dans ce blog.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top