Question: I try to write a single makefile, which search for lib-directories in the current directory, compile the sources of every directory and put the object-file into a separate object-directory. I don't want to have more than one makefile.

This makefile will do this:

```
SRCDIR  := $(shell ls -d lib_*/)

CC      := gcc
DB      := gdb
OBJDIR  := obj
CFLAGS  := -Wall -Werror -Wextra -pedantic -O3
LDFLAGS := #

# Rules
all:
    @ # create object directory
    @mkdir -p  $(OBJDIR)/ ;
    @ # go through all source dirs
    @for dir in $(SRCDIR); do \
        echo $$dir && \
        cd $$dir && \
        for n in $$(ls *.c); do \
            m=$${n%%.c}; \
            $(CC) -c \
               $(CFLAGS) \
               $(LDFLAGS) \
               -o ../$(OBJDIR)/$$m.o $$n;\
        done; \
        cd ..; \
    done

```

But: The makefile compiles every run all sources. Also the the sources without any changes. If it possible that the makefile recognizes if there are changes or not and compiles only the changed sources?

---

Here the strcture of the dirs:

```
lib
 |-lib_one
 |  |-lib_one.c
 |  |-lib_one.h
 |
 |-lib_two
 |  |-lib_two.c
 |  |-lib_two.h
 |
 |-lib_n
 |  |-lib_n.c
 |  |-lib_n.h
 |
 |-obj
 |  |-lib_one.o
 |  |-lib_two.o
 |  |-
 |  |-lib_n.o
 |
 |-makefile

```

Answer: 
If you don't care about header files, you can do this:

```
SRCS := $(wildcard */*.c)

OBJDIR := obj

OBJS := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SRCS)))

all: $(OBJS)
    @:

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

vpath %.c $(wildcard *)

```

If you care about the obvious header files (e.g. `lib_one.c` includes `lib_one.h`), then you can make a simple adjustment:

```
$(OBJDIR)/%.o: %.c %.h
    $(CC) -c $(CFLAGS) -o $@ $<

vpath %.c $(wildcard *)
vpath %.h $(wildcard *)

```

If you have other dependencies (e.g. `lib_n.c` includes `lib_one.h`), you could add them by hand:

```
lib_n.o: lib_one.h

```

or you could use [Advanced Auto-Dependency Generation](http://mad-scientist.net/make/autodep.html), but that's an advanced technique I'd advise you to leave for another day.
You can use the following: 

```
SRCDIR  := $(shell ls -d lib_*/)

CC      := gcc
DB      := gdb
OBJDIR  := obj
CFLAGS  := -Wall -Werror -Wextra -pedantic -O3
LDFLAGS := #

# Rules
all:
    @ # create object directory
    @mkdir -p  $(OBJDIR)/ ;
    @ # go through all source dirs
    @for dir in $(SRCDIR); do \
        echo $$dir && \
        cd $$dir && \
        for n in $$(ls *.c); do \
            m=$${n%%.c}; \
            if [ ! -e ../$(OBJDIR)/$$m.o ] || \
                [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$n` ] || \
                ([ -e $$m.h ] && [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$m.h` ]); then \
                echo "Change detected, compiling $$n..."; \
                $(CC) -c \
                    $(CFLAGS) \
                    $(LDFLAGS) \
                    -o ../$(OBJDIR)/$$m.o $$n;\
            fi; \
        done; \
        cd ..; \
    done

```

The following line adds a check over the object files to see if they exists, if that then it compare source modification time against object modification time (kind of repeating the `make` work inside `make`).

```
 if [ ! -e ../$(OBJDIR)/$$m.o ] || [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$n` ] || ([ -e $$m.h ] && [ `stat -c %Y ../$(OBJDIR)/$$m.o` -lt `stat -c %Y $$m.h` ]); then 

```