The GNU standard says it is a good idea to not use the -p
command for mkdir
:
For example, don’t use ‘mkdir -p’, convenient as it may be, because a few systems don’t support it at all and with others, it is not safe for parallel execution
I would like to adhere to this standard and thus I am running into a problem in my Makefile.
I am recursively compiling all C sources from all directories within the src
directory and would like to place them inside the obj
directory. The same directory structure is mirrored inside the obj
directory, however these directories do not initially exist.
I could very easily do mkdir -p $(@D)
to create my directories, but following GNU's standard, I cannot do this, which brings me to my question: How can I work around this in a Makefile?
My Makefile below:
SRCDIR=src
OBJDIR=obj
CC=cc
CFLAGS=
CFLAGS=-g -O2 -pedantic -Wall
ALL_CFLAGS=-std=c89 $(CFLAGS)
# Copied from https://stackoverflow.com/questions/2483182/recursive-wildcards-in-gnu-make/18258352#18258352
rwildcard=$(foreach d, $(wildcard $1/*), $(call rwildcard, $d, $2) $(filter $(subst *, %, $2), $d))
SOURCES=$(call rwildcard, $(SRCDIR), *.c)
OBJECTS=$(subst $(SRCDIR),$(OBJDIR),$(SOURCES:.c=.o))
all: $(OBJECTS)
$(OBJDIR)/%.o: $(SRCDIR)/%.c
$(CC) $(ALL_CFLAGS) -c -o $@ $<
The GNU standards are outdated in many places. This appears to be one of these places.
Nowadays, mkdir -p
is part of POSIX. It is not even a recent invention because it came from System V.
Since your makefile assumes that the C compiler is GCC (or at least has a GCC-compatible command line syntax), you might as well assume that mkdir -p
works. If you want users an easy way to override it if it does not for them, you could add this:
MKDIR_P = mkdir -p
and use $(MKDIR_P)
in recipes, in place of mkdir -p
.
But all this really shouldn't be necessary. Even GNU's supposedly-portable mkinstalldirs
script has been using mkdir -p
for a long, long time.