Question

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
Was it helpful?

Solution

On UNIX Just use this:

mkdir -p $(OBJDIR)

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

OTHER TIPS

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.

You can use the test command:

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

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.

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

Inside your makefile:

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

On Windows

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

On Unix | Linux

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

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

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

$(OBJDIRS):
    mkdir $@

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

It works under mingw32/msys/cygwin/linux

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

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top