CONFIG :=
DEFINE :=
INCLUDE := -Icommon
CFLAGS := -Wall -Wextra -Werror -std=c++11 -O2 $(EXTRA_CFLAGS)
LDFLAGS := $(EXTRA_LDFLAGS)
LIBS := -lBlinkenLib $(EXTRA_LIBS)
LAST_LIBS :=
TARGET := Blinker
ifeq ($(CROSS_WIN),1)
CXX := x86_64-w64-mingw32-g++
PLATFORM := windows
LDFLAGS += -static
LAST_LIBS += -lws2_32
TARGET := Blinker.exe
else
CXX := g++
PLATFORM := linux
LIBS += -lpthread
endif
INCLUDE += -I$(PLATFORM)

CFGS := $(wildcard config/*.cfg.sh)
CFGS_BASE := $(patsubst %.cfg.sh,%,$(CFGS))
CFGS_MK := $(addsuffix .cfg.mk,$(CFGS_BASE))

SRCS := $(wildcard common/*.cpp) $(wildcard $(PLATFORM)/*.cpp)
SRCS_BASE := $(patsubst %.cpp,%,$(SRCS))
DEPS := $(addprefix obj/,$(addsuffix .d,$(SRCS_BASE)))
OBJS := $(addprefix obj/,$(addsuffix .o,$(SRCS_BASE)))

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

all: $(DEPS) $(TARGET)

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

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

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

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

obj:
	mkdir $@ $@/common $@/$(PLATFORM)

obj/%.d: %.cpp Makefile config.mk | obj
	$(CXX) $(DEFINE) $(INCLUDE) $(CFLAGS) -MM -MT $(@:.d=.o) -o $@ $<

obj/%.o: %.cpp Makefile | obj
	$(CXX) $(DEFINE) $(INCLUDE) $(CFLAGS) -c -o $@ $<

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

clean:
	rm -rf obj $(TARGET)

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