how to prevent "directory already exists error" in a makefile when using mkdir

MakefileDirectoryExists

Makefile Problem Overview


I need to generate a directory in my makefile and I would like to not get the "directory already exists error" over and over even though I can easily ignore it.

I mainly use mingw/msys but would like something that works across other shells/systems too.

I tried this but it didn't work, any ideas?

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

Makefile Solutions


Solution 1 - Makefile

Looking at the official make documentation, here is a good way to do it:

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)

You should see here the usage of the | pipe operator, defining an order only prerequisite. Meaning that the $(OBJDIR) target should be existent (instead of more recent) in order to build the current target.

Note that I used mkdir -p. The -p flag was added compared to the example of the docs. See other answers for another alternative.

Solution 2 - Makefile

On UNIX Just use this:

mkdir -p $(OBJDIR)

The -p option to mkdir prevents the error message if the directory exists.

Solution 3 - Makefile

You can use the test command:

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

Solution 4 - Makefile

Here is a trick I use with GNU make for creating compiler-output directories. First define this rule:

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

Then make all files that go into the directory dependent on the .d file in that directory:

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

Note use of $< instead of $^.

Finally prevent the .d files from being removed automatically:

 .PRECIOUS: %/.d

Skipping the .d file, and depending directly on the directory, will not work, as the directory modification time is updated every time a file is written in that directory, which would force rebuild at every invocation of make.

Solution 5 - Makefile

If having the directory already exist is not a problem for you, you could just redirect stderr for that command, getting rid of the error message:

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

Solution 6 - Makefile

Inside your makefile:

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

Solution 7 - Makefile

On Windows

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

On Unix | Linux

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

Solution 8 - Makefile

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

Solution 9 - Makefile

$(OBJDIR):
    mkdir $@

Which also works for multiple directories, e.g..

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

$(OBJDIRS):
    mkdir $@

Adding $(OBJDIR) as the first target works well.

Solution 10 - Makefile

It works under mingw32/msys/cygwin/linux

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

Solution 11 - Makefile

A little simpler than Lars' answer:

something_needs_directory_xxx : xxx/..

and generic rule:

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

No touch-files to clean up or make .PRECIOUS :-)

If you want to see another little generic gmake trick, or if you're interested in non-recursive make with minimal scaffolding, you might care to check out Two more cheap gmake tricks and the other make-related posts in that blog.

Solution 12 - Makefile

If you explicitly ignore the return code and dump the error stream then your make will ignore the error if it occurs:

mkdir 2>/dev/null || true

This should not cause a race hazard in a parallel make - but I haven't tested it to be sure.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKPexEAView Question on Stackoverflow
Solution 1 - MakefileofavreView Answer on Stackoverflow
Solution 2 - MakefiletchenView Answer on Stackoverflow
Solution 3 - MakefileskymtView Answer on Stackoverflow
Solution 4 - MakefileNorthern StreamView Answer on Stackoverflow
Solution 5 - MakefileandrewdotnichView Answer on Stackoverflow
Solution 6 - MakefileLee HView Answer on Stackoverflow
Solution 7 - MakefilewmadView Answer on Stackoverflow
Solution 8 - MakefileMichael McCartyView Answer on Stackoverflow
Solution 9 - MakefileMartin FidoView Answer on Stackoverflow
Solution 10 - MakefilelygstateView Answer on Stackoverflow
Solution 11 - MakefileMischaView Answer on Stackoverflow
Solution 12 - MakefileAndrewView Answer on Stackoverflow