Makefile to build library I'm starting with make, and I made my first makefile to build my project. I don't know if it's the best way to do it or not, so I share with you my makefile to get your opinion on it:

Directory structure:




├── LICENSE
├── Makefile
├── objs
│   └── parser.o
├── out
│   ├── libsip.a
│   └── parser.h
├── README.md
├── src
│   ├── parser.c
│   ├── parser.d
│   └── parser.h
└── tests
    ├── a.out
    ├── config.ini
    ├── libsip.a
    ├── parser.h
    └── test.c



Makefile:



SHELL = /bin/sh

CC := gcc
CFLAGS := -Wall

SRCSDIR := src
OBJSDIR := objs
OUTDIR := out

SRCS := $(wildcard $(SRCSDIR)/*.c) 
OBJS := $(SRCS:$(SRCSDIR)/%.c=$(OBJSDIR)/%.o)


$(OUTDIR)/libsip.a : $(OBJS)
    @mkdir -p $(@D)
    ar cr -o $@ $^
    cp -f src/parser.h $(OUTDIR)

$(OBJSDIR)/%.o : $(SRCSDIR)/%.c
    @mkdir -p $(@D)
    $(CC) $(CFLAGS) $&lt; -c -o $@  
    $(CC) -MM $&lt; &gt; $(patsubst %.c, %.d, $&lt;) &amp;&amp; \
    sed -i \ '1s|^|$(@D)/|' $(patsubst %.c, %.d, $&lt;) 
# use sed to add path to object dependencies

.PHONY : clean 
clean :
    rm -rf $(OBJSDIR) $(OUTDIR)

-include $(SRCS:%.c=%.d)
Use of the naked utilities (cp, mkdir, sed, and especially rm) is usually frowned upon. It makes your makefile vulnerable to a path attack; aliasing may also result in some strangeness (for example, many distros come with rm aliased to rm -i); also keep in mind that GNU make works nativly in Windows environment, which lacks those utilities.

Typically what you do is to define them like RM := /bin/rm (conditionally tailoring for all expected platforms), etc and forget all the complications once and forever. Or use autotools.
mkdir fails if the target directory exists. -mkdir is a usual practice.
I prefer to have separate rules for dependencies and objects. Having them combined, make builds the .o file based on old dependencies. You may end up in an inconsistent state.