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

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

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

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

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

Ответ 1

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

mkdir -p $(OBJDIR)

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

Ответ 2

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

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)

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

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

Ответ 3

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

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

Ответ 4

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

  %/.d:
          mkdir -p $(@D)
          touch [email protected]

Затем создайте все файлы, которые входят в каталог, зависящий от .d файла в этом каталоге:

 obj/%.o: %.c obj/.d
    $(CC) $(CFLAGS) -c -o [email protected] $<

Примечание использования $< вместо $^.

Наконец, чтобы файлы .d удалялись автоматически:

 .PRECIOUS: %/.d

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

Ответ 5

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

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

Ответ 6

Внутри вашего файла makefile:

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

Ответ 7

В Windows

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

В Unix | Linux

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi

Ответ 8

ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif

Ответ 9

$(OBJDIR):
    mkdir [email protected]

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

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

$(OBJDIRS):
    mkdir [email protected]

Добавление $(OBJDIR), поскольку первая цель работает хорошо.

Ответ 10

Он работает под управлением mingw32/msys/cygwin/linux

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

Ответ 11

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

something_needs_directory_xxx : xxx/..

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

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

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

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

Ответ 12

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

mkdir 2>/dev/null || true

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