как предотвратить "каталог уже существует ошибка" в файле makefile при использовании mkdir



Мне нужно создать каталог в моем makefile, и я хотел бы не получить "каталог уже существует ошибка" снова и снова, хотя я могу легко игнорировать его.



Я в основном использую mingw/msys, но хотел бы что-то, что работает и в других оболочках / системах.



Я пробовал это, но это не сработало, какие-то идеи?



ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
625   12  

12 ответов:

в UNIX просто используйте это:

mkdir -p $(OBJDIR)

параметр-p для mkdir предотвращает сообщение об ошибке, если каталог существует.

смотрим официальная документация, вот хороший способ сделать это:

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)

вы должны увидеть здесь использование оператора / pipe, определяющего только предварительное условие заказа. Это означает, что $(OBJDIR) цель должна существовать (вместо последние) для того, чтобы построить текущую цель.

обратите внимание, что я использовал mkdir -p. Элемент -p флаг был добавлен по сравнению с примером документов. См. другие ответы для другого альтернатива.

вы можете использовать тестовую команду:

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

вот трюк, который я использую с GNU make для создания каталогов вывода компилятора. Сначала определите это правило:

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

затем сделать все файлы, которые идут в каталог зависит от .д файл в эту директорию:

 obj/%.o: %.c obj/.d
    $(CC) $(CFLAGS) -c -o $@ $<

обратите внимание на использование $

наконец-то предотвратить .D файлы удаляются автоматически:

 .PRECIOUS: %/.d

пропуск .D файл, и в зависимости непосредственно от каталога, не будет работать, так как каталог время модификации обновляется каждый раз, когда файл записывается в этот каталог, что заставит перестроить при каждом вызове make.

внутри вашего makefile:

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

Если каталог уже существует-это не проблема для вас, вы можете просто перенаправить stderr для этой команды, избавившись от сообщения об ошибке:

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

На Windows

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

На Unix / Linux

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

который также работает для нескольких каталогов, например.

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

$(OBJDIRS):
    mkdir $@

добавлять $(OBJDIR) как первая цель работает хорошо.

он работает под mingw32 / msys / cygwin / linux

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

Если вы явно игнорируете код возврата и сбрасываете поток ошибок, то ваш make будет игнорировать ошибку, если она произойдет:

mkdir 2>/dev/null || true

Это не должно вызывать опасности гонки в параллельном make - но я не проверял его, чтобы быть уверенным.

немного проще, чем ответ Ларса:

something_needs_directory_xxx : xxx/..

и общее правило:

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

нет сенсорных файлов для очистки или создания .Драгоценные : -)

Если вы хотите увидеть еще один маленький общий трюк gmake, или если вы заинтересованы в нерекурсивном создании с минимальными лесами, вы можете проверить еще два дешевых трюка gmake и другие связанные с созданием сообщения в этом блоге.

Comments

    Ничего не найдено.