Ответ 1
В UNIX Просто используйте это:
mkdir -p $(OBJDIR)
Параметр -p для mkdir предотвращает сообщение об ошибке, если каталог существует.
Мне нужно создать каталог в моем make файле, и я бы не хотел, чтобы "каталог уже существует ошибка" снова и снова, хотя я могу легко игнорировать его.
В основном я использую mingw/msys, но мне нравится что-то, что работает и с другими оболочками/системами.
Я пробовал это, но это не сработало, никаких идей?
ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
В 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)
Здесь вы должны увидеть использование | оператор трубы, определяя заказ только предварительным условием.
Это означает, что цель $(OBJDIR)
должна существовать (вместо более поздней) для создания текущей цели.
Обратите внимание, что я использовал mkdir -p
. Флаг -p
был добавлен по сравнению с примером документов.
См. Другие ответы для другой альтернативы.
Вы можете использовать команду тестирования:
test -d $(OBJDIR) || mkdir $(OBJDIR)
Вот трюк, который я использую с 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.
Если каталог уже существует, это не проблема для вас, вы можете просто перенаправить stderr для этой команды, избавившись от сообщения об ошибке:
-mkdir $(OBJDIR) 2>/dev/null
Внутри вашего файла makefile:
target:
if test -d dir; then echo "hello world!"; else mkdir dir; fi
В 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 [email protected]
Что также работает для нескольких каталогов, например.
OBJDIRS := $(sort $(dir $(OBJECTS)))
$(OBJDIRS):
mkdir [email protected]
Добавление $(OBJDIR)
, поскольку первая цель работает хорошо.
Он работает под управлением mingw32/msys/cygwin/linux
ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
Немного проще ответа Ларса:
something_needs_directory_xxx : xxx/..
и общее правило:
%/.. : ;@mkdir -p $(@D)
Никаких сенсорных файлов для очистки или создания .PRECIOUS: -)
Если вы хотите увидеть еще один небольшой общий трюк gmake или если вы заинтересованы в нерекурсивном создании с минимальными лесами, вам может потребоваться проверить Еще два дешевых трюка gmake и другие связанные с ним сообщения в этом блоге.
Если вы явно игнорируете код возврата и выгружаете поток ошибок, ваш make игнорирует ошибку, если это происходит:
mkdir 2>/dev/null || true
Это не должно приводить к возникновению расовой опасности в параллельном режиме - но я не проверял ее, чтобы быть уверенным.