CFGS := $(wildcard config/*.cfg.sh)
SRCS := $(wildcard common/*.cpp) $(wildcard linux/*.cpp)
TARGET := Blinker

CPP := g++
CONFIG :=
DEFINE :=
INCLUDE := -Icommon -Ilinux
CFLAGS := -Wall -Wextra -Werror -O2 -g2
LDFLAGS :=
LIBS := -lBlinkenLib

CFGS_BASE := $(patsubst %.cfg.sh,%,$(CFGS))
CFGS_MK := $(addsuffix .cfg.mk,$(CFGS_BASE))
SRCS_BASE := $(patsubst %.cpp,%,$(SRCS))
DEPS := $(addsuffix .d,$(SRCS_BASE))
OBJS := $(addsuffix .o,$(SRCS_BASE))

.PHONY: all clean distclean
.SUFFIXES:
.SECONDARY:

all: $(TARGET)

ifneq ($(MAKECMDGOALS),clean)
  ifneq ($(MAKECMDGOALS),distclean)
    include config.mk
    include deps
  endif
endif

DEFINE += -DBLINKER_CONFIG="\"$(CONFIG)\""

config.mk: $(CFGS_MK)
	cat /dev/null $^ >$@

%.cfg.mk: %.cfg.sh
	sh $< >$@

deps: $(DEPS)
	cat /dev/null $^ >$@

%.d: %.cpp Makefile config.mk
	$(CPP) $(DEFINE) $(INCLUDE) $(CFLAGS) -M -o $@ $<
	sed -i 1s!^!$(dir $<)! $@

%.o: %.cpp Makefile
	$(CPP) $(DEFINE) $(INCLUDE) $(CFLAGS) -c -o $@ $<

$(TARGET): $(OBJS)
	$(CPP) $(LDFLAGS) -o $@ $+ $(LIBS)

clean:
	rm -f deps $(DEPS) $(OBJS) $(TARGET)

distclean: clean
	rm -f config.mk $(CFGS_MK)