SHELL=/bin/bash
OPTFLAGS=-O2 -flto -g
EXPORTFLAGS=-fvisibility=hidden -fpic -Wl,--export-dynamic
CPPFLAGS=-std=gnu++11 -I../include -I../../include
LIBSFLAGS=
WARNFLAGS=-Wall

CFLAGS+=$(OPTFLAGS) $(EXPORTFLAGS) $(WARNFLAGS) $(CPPFLAGS)
LDFLAGS+=$(OPTFLAGS) $(EXPORTFLAGS) $(WARNFLAGS) $(LIBSFLAGS)

CC=g++

ifdef MODULE

default: $(MODULE).so

SOURCE = $(wildcard *.cpp)
-include makemod
DEPENDS = $(subst .cpp,.d,$(SOURCE))
OBJECTS = $(subst .cpp,.o,$(SOURCE))

$(MODULE).so: $(OBJECTS)
	 $(CC) -shared -o $@ $(OBJECTS) $(LDFLAGS) $(MODLIBS)

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

%.d: %.cpp
	 $(CC) $(CPPFLAGS) -MM -MT $(subst .cpp,.o,$<) $< | sed 's%\(^.*\):%\1 $@ :%g' >$@

include $(DEPENDS)

clean:
	 rm -f *.d *.o

distclean: clean
	 rm -f $(MODULE).so

else

default: modules

MODDIRS = $(wildcard modules/*)
MODDIRS+= $(wildcard extramodules/*)

MODSOURCE = $(wildcard modules/*/*.cpp extramodules/*/*.cpp)
MODHEADERS = $(wildcard modules/*/*.h extramodules/*/*.h)
-include $(wildcard modules/*/makemod) $(wildcard extramodules/*/makemod)
MODOBJECTS = $(subst .cpp,.o,$(MODSOURCE))
MODDEPS = $(subst .cpp,.d,$(MODSOURCE))

modules: $(MODSOURCE) $(MODHEADERS)
	 [ -d bin ] || mkdir bin
	 for dir in $(MODDIRS); do\
	  mod=$${dir/*\//};\
	  make -C $$dir -f ../../Makefile MODULE=$$mod && ln -sf ../$$dir/$${mod}.so bin/$${mod}.so;\
	 done

all: modules makemap

makemap: $(MODOBJECTS)
	 [ -d bin ] || mkdir bin
	 make -C src MODLIBS="$(MODLIBS)" MODOBJECTS="$(patsubst %,../%,$(MODOBJECTS))" && ln -sf ../src/makemap bin/makemap

$(MODOBJECTS): $(MODSOURCE) $(MODHEADERS)
	 for dir in $(MODDIRS); do\
	  make -C $$dir -f ../../Makefile MODULE=$${dir/*\//};\
	 done

clean:
	 for dir in $(MODDIRS); do\
	  make -C $$dir -f ../../Makefile MODULE=$${dir/*\//} clean;\
	 done
	 make -C src clean

distclean:
	 for dir in $(MODDIRS); do\
	  make -C $$dir -f ../../Makefile MODULE=$${dir/*\//} distclean;\
	 done
	 make -C src distclean
	 rm -f bin/*
	 rmdir bin
endif