LIBNAME := $(shell basename $$(pwd))
MAJOR := 1
MINOR := 0.0

UNAME_S := $(shell uname -s)

ifeq ($(UNAME_S),Darwin)
	LINKERNAME := $(LIBNAME).dylib
	SONAME := $(LIBNAME).$(MAJOR).dylib
	REALNAME := $(LINKERNAME)
else
	LINKERNAME := $(LIBNAME).so
	SONAME := $(LINKERNAME).$(MAJOR)
	REALNAME := $(SONAME).$(MINOR)
endif

PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
LIBDIR ?= $(PREFIX)/lib
INCLUDEDIR ?= $(PREFIX)/include
DATADIR ?= $(PREFIX)/share
MANDIR ?= $(DATADIR)/man

SRCS := $(wildcard *.cpp)
OBJS := $(subst .cpp,.o,$(SRCS))
DEPS := $(subst .cpp,.d,$(SRCS))
HDRS := $(filter-out $(LIBNAME).hpp,$(wildcard *.hpp))

CXX ?= g++

CXXFLAGS := $(CXXFLAGS) -Wshadow -Wall -Wpedantic -Wextra -g -fno-strict-aliasing -std=c++17 -fPIC
ifeq ($(DEBUG),1)
	CXXFLAGS += -D DEBUG -O0
else
	CXXFLAGS += -D NDEBUG -O3
endif

LDLIBS :=

RM := /bin/rm -f
INSTALL := /usr/bin/install -c

all: $(REALNAME)

$(REALNAME): $(OBJS) $(DEPS)
ifeq ($(UNAME_S),Darwin)
	$(CXX) -dynamiclib -o $(REALNAME) -current_version $(MAJOR) -compatibility_version $(MINOR) $(LDFLAGS) $(LDLIBS) $(OBJS)
else
	$(CXX) -g -shared -Wl,-soname,$(SONAME) -o $(REALNAME) $(LDFLAGS) $(LDLIBS) $(OBJS)
endif

%.o: %.cpp %.d Makefile
	$(CXX) $(CXXFLAGS) -MMD -MP -MT $@ -MF $*.d -c $<

-include *.d

%.d: ;

$(LIBNAME).hpp: $(HDRS)
	@echo updating $(LIBNAME).hpp
	@cp /dev/null $(LIBNAME).hpp
	@for h in $(HDRS); \
	do \
		cat $$h >> $(LIBNAME).hpp; \
	done	

.PHONY: clean install

clean:
	$(RM) $(OBJS) $(DEPS) $(REALNAME) $(LIBNAME).hpp

install: $(REALNAME) $(LIBNAME).hpp
	$(INSTALL) -m 644 $(REALNAME) $(LIBDIR)
	$(INSTALL) -m 644 $(LIBNAME).hpp $(INCLUDEDIR)
ifeq ($(UNAME_S),Darwin)
	cd $(LIBDIR) && ln -sf $(REALNAME) $(SONAME)
else
	ldconfig
	cd $(LIBDIR) && ln -sf $(SONAME) $(LINKERNAME)
endif