Reputation: 16778
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
Upvotes: 123
Views: 134702
Reputation: 2298
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.
Upvotes: 0
Reputation: 101
On Windows
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
On Unix | Linux
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
Upvotes: 10
Reputation: 2242
On UNIX Just use this:
mkdir -p $(OBJDIR)
The -p option to mkdir prevents the error message if the directory exists.
Upvotes: 128
Reputation: 4786
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.
Upvotes: 129
Reputation: 3061
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.
Upvotes: 0
Reputation: 381
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.
Upvotes: 19
Reputation: 561
It works under mingw32/msys/cygwin/linux
ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif
Upvotes: 3
Reputation: 1090
$(OBJDIR):
mkdir $@
Which also works for multiple directories, e.g..
OBJDIRS := $(sort $(dir $(OBJECTS)))
$(OBJDIRS):
mkdir $@
Adding $(OBJDIR)
as the first target works well.
Upvotes: 6
Reputation: 16804
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
Upvotes: 13
Reputation: 709
ifeq "$(wildcard $(MY_DIRNAME) )" ""
-mkdir $(MY_DIRNAME)
endif
Upvotes: 7
Reputation: 5177
Inside your makefile:
target:
if test -d dir; then echo "hello world!"; else mkdir dir; fi
Upvotes: 11