como evitar “diretório já existe erro” em um makefile ao usar mkdir
Pergunta
Eu preciso gerar um diretório no meu makefile e eu gostaria de não obter o "diretório já existe erro" mais e mais, mesmo que eu posso facilmente ignorá-lo.
Eu uso principalmente MinGW / msys mas gostaria de algo que funciona em outras conchas / sistemas também.
Eu tentei isso, mas não deu certo, todas as idéias?
ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
Solução
No UNIX Basta usar este:
mkdir -p $(OBJDIR)
A opção -p para mkdir impede que a mensagem de erro se o diretório existe.
Outras dicas
Olhando para a documentação make oficial , aqui está uma boa maneira de fazê-lo:
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir -p $(OBJDIR)
Você deverá ver aqui o uso do | operador de tubo, que define uma ordem único pré-requisito.
O que significa que o alvo $(OBJDIR)
deve ser existente (em vez de mais recente ), a fim de construir o alvo atual.
Note que eu usei mkdir -p
. A bandeira -p
foi adicionado em comparação com o exemplo dos documentos.
Veja outras respostas para uma outra alternativa.
Você pode usar o comando de teste:
test -d $(OBJDIR) || mkdir $(OBJDIR)
Aqui é um uso I truque com GNU make para a criação de diretórios compilador de saída. Primeiro defina essa regra:
%/.d:
mkdir -p $(@D)
touch $@
Em seguida, fazer todos os arquivos que vão para o diretório depende do arquivo .d nesse diretório:
obj/%.o: %.c obj/.d
$(CC) $(CFLAGS) -c -o $@ $<
uso Nota de US $
Por fim impedir que os arquivos .d de serem removidos automaticamente: Ignorando o arquivo .d, e dependendo diretamente no diretório, não vai funcionar, como o tempo de modificação do diretório é atualizado a cada vez que um arquivo é gravado no diretório, o que forçaria reconstruir em cada invocação de make. .PRECIOUS: %/.d
Se ter o diretório já existe não é um problema para você, você poderia stderr apenas redirecionamento para esse comando, se livrar da mensagem de erro:
-mkdir $(OBJDIR) 2>/dev/null
Dentro do seu makefile:
target:
if test -d dir; then echo "hello world!"; else mkdir dir; fi
No Windows
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
No Unix | Linux
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
ifeq "$(wildcard $(MY_DIRNAME) )" ""
-mkdir $(MY_DIRNAME)
endif
$(OBJDIR):
mkdir $@
O que também trabalha para vários diretórios, por exemplo ..
OBJDIRS := $(sort $(dir $(OBJECTS)))
$(OBJDIRS):
mkdir $@
Adicionando $(OBJDIR)
como o primeiro alvo funciona bem.
Ele funciona sob mingw32 / msys / cygwin / linux
ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
Se você ignorar explicitamente o código de retorno e despejar o fluxo de erro, em seguida, sua marca irá ignorar o erro se ocorrer:
mkdir 2>/dev/null || true
Este não deve provocar riscos de corrida em um make paralelo -. Mas eu não testei ele para ter certeza
Um pouco mais simples do que resposta Lars':
something_needs_directory_xxx : xxx/..
e regra genérica:
%/.. : ;@mkdir -p $(@D)
No Touch-arquivos para limpar ou fazer .PRECIOUS: -)
Se você quiser ver um outro truque gmake pouco genérico, ou se você estiver interessado em fazer não recursivo com andaimes mínima, você pode cuidar de verificar dois truques GCertifique mais barato eo outro make-relacionados nesse blog.