PROJECT_VERSION :=$(shell echo `git describe --long --tags | sed -e "s/^[ a-z_-]\+\([0-9.]\+\)/\1/;s/\([^-]*-g\)/r\1/;s/-/./g"`)
DMD=dmd
DMD_FLAGS=-de -w -J./views -I./src/sdp -linker=ld.gold
DMD_FLAGS_RELEASE=-O -inline -release
DMD_FLAG_BINOF=-of
LDC=ldc2
LDC_FLAGS=-w -J=views -I=src/sdp -linker=ld.gold
LDC_FLAGS_RELEASE=-O4 -inline -release
LDC_FLAG_BINOF=-of=
GDC=gdc
GDC_FLAGS=
GDC_FLAGS_RELEASE=-march=native -O3 -pipe -frelease
GDC_FLAG_BINOF=-o
RDMD=rdmd
RDMD_FLAGS=--build-only --compiler=
DUB=dub
DUB_FLAGS=-v --force --compiler=
# SET_D_COMPILER=(one of: DMD LDC or GDC):
SET_D_COMPILER=LDC
SET_DC_FLAGS_DEBUG_EXTRA=-debug=dumpdoc
DC=$($(SET_D_COMPILER))
DC_FLAGS=$($(shell echo $(SET_D_COMPILER)_FLAGS))
DC_FLAGS_RELEASE=$($(shell echo $(SET_D_COMPILER)_FLAGS_RELEASE))
DC_FLAG_BINOF=$($(shell echo $(SET_D_COMPILER)_FLAG_BINOF))
DC_FLAGS_DEBUG_DEFAULT_SET=-unittest -debug=checkdoc -debug=summary
DC_FLAGS_DEBUG_SET=\
	$(shell echo $(DC_FLAGS_DEBUG_DEFAULT_SET) $(SET_DC_FLAGS_DEBUG_EXTRA))
ifeq ($(DC), $(DMD))
	DC_FLAGS_DEBUG :=$(shell echo $(DC_FLAGS_DEBUG_SET))
endif
ifeq ($(DC) ,$(LDC))
	DC_FLAGS_DEBUG :=$(shell echo $(DC_FLAGS_DEBUG_SET)| sed -e "s/-debug=/-d-debug=/g")
endif
ifeq ($(DC), $(GDC))
	DC_FLAGS_DEBUG :=$(shell echo $(DC_FLAGS_DEBUG_SET)| sed -e "s/-debug/-fdebug/g")
endif
DUB_FLAGS_DEBUG :=$(shell echo $(DC_FLAGS_DEBUG_SET)| sed -e "s/-debug/--debug/g"| sed -e "s/-unittest//g")
PRG_NAME=sdp
PRG_SRC=$(PRG_NAME).d
PRG_SRCDIR=./src
PRG_BIN=$(PRG_NAME)
PRG_BINDIR=./bin
PRG_DOCDIR=./docs
# ORG
ORG_VERSION=20161214
EMACSLISP=/usr/share/emacs/site-lisp
EMACSLISP_ORG=~/.emacs.d/elpa/org-$($(shell echo $(ORG_VERSION)))
EMACSLISP_ORG_CONTRIB=~/.emacs.d/elpa/org-plus-contrib-$($(shell echo $(ORG_VERSION)))
ORGFILELIST=$(shell echo `ls -1 maker.org org/*.org`)
ORGFILES=""
ORGDIR=$(shell echo `pwd`)
all: tangle build

build: $(PRG_SRCDIR)/$(PRG_SRC)
	$(DC) $(DC_FLAGS) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)

rebuild: $(PRG_SRCDIR)/$(PRG_SRC) $(PRG_BINDIR)/$(PRG_BIN).o clean build

makefile_new:
	make -k tangle_maker
dub: $(PRG_SRCDIR)/$(PRG_SRC)
	$(DUB) $(DUB_FLAGS)$(DC)
debug_dub: $(PRG_SRCDIR)/$(PRG_SRC)
	$(DUB) $(DUB_FLAGS)$(DC) $(DUB_FLAGS_DEBUG)
all_builds_quick:
	$(DUB) --compiler=dmd --config=sdp-dmd-version
	mv bin/sdp-dmd-ver bin/sdp-$(PROJECT_VERSION)-dmd
	$(DUB) --compiler=ldc2 --config=sdp-ldc-version
	mv bin/sdp-ldc-ver bin/sdp-$(PROJECT_VERSION)-ldc
	$(DUB) --compiler=gdc --config=sdp-gdc-version
	mv bin/sdp-gdc-ver bin/sdp-$(PROJECT_VERSION)-gdc
all_builds_quick_release:
	$(DUB) --compiler=dmd --config=sdp-dmd-version
	mv bin/sdp-dmd-ver bin/sdp-$(PROJECT_VERSION)-dmd
	$(DUB) --compiler=ldc2 --config=sdp-ldc-version
	mv bin/sdp-ldc-ver bin/sdp-$(PROJECT_VERSION)-ldc
	$(DUB) --compiler=gdc --config=sdp-gdc-version
	mv bin/sdp-gdc-ver bin/sdp-$(PROJECT_VERSION)-gdc
all_builds: clean skel tangle
	$(DUB) --compiler=dmd --config=sdp-dmd-version
	mv bin/sdp-dmd-ver bin/sdp-$(PROJECT_VERSION)-dmd
	$(DUB) --compiler=ldc2 --config=sdp-ldc-version
	mv bin/sdp-ldc-ver bin/sdp-$(PROJECT_VERSION)-ldc
	$(DUB) --compiler=gdc --config=sdp-gdc-version
	mv bin/sdp-gdc-ver bin/sdp-$(PROJECT_VERSION)-gdc
all_builds_debug: clean skel tangle
	$(DUB) --compiler=dmd --config=sdp-dmd-debug-version
	mv bin/sdp-dmd-debug-ver bin/sdp-$(PROJECT_VERSION)-dmd-debug
	$(DUB) --compiler=ldc2 --config=sdp-ldc-debug-version
	mv bin/sdp-ldc-debug-ver bin/sdp-$(PROJECT_VERSION)-ldc-debug
	$(DUB) --compiler=gdc --config=sdp-gdc-debug-version
	mv bin/sdp-gdc-debug-ver bin/sdp-$(PROJECT_VERSION)-gdc-debug
ver:
	echo sdp-$(PROJECT_VERSION)
# dmd
dmd_rel: expunge skel tangle
	$(DUB) --compiler=dmd --config=sdp-release
dmd_stamp:
	$(DUB) --compiler=dmd --config=sdp-dmd
dmd_ver:
	$(DUB) --compiler=dmd --config=sdp-dmd
	mv bin/sdp-dmd bin/sdp-dmd-$(PROJECT_VERSION)
dmd_release: expunge skel tangle
	$(DUB) --compiler=dmd --config=sdp-release
dmd_release_stamp:
	$(DUB) --compiler=dmd --config=sdp-dmd
dmd_release_stamp_version:
	$(DUB) --compiler=dmd --config=sdp-dmd
	mv bin/sdp-dmd bin/sdp-dmd-$(PROJECT_VERSION)
dmd_release_tangle: tangle
	$(DUB) --compiler=dmd --config=sdp-dmd
dmd_release_expunge_tangle: expunge skel tangle
	$(DUB) --compiler=dmd --config=sdp-dmd
dmd_debug:
	$(DUB) --compiler=dmd --config=sdp-dmd-debug
dmd_debug_tangle: tangle
	$(DUB) --compiler=dmd --config=sdp-dmd-debug
dmd_debug_docs: clean_docs tangle
	$(DUB) --compiler=dmd --config=sdp-dmd-debug-docs
dmd_debug_unittest: tangle
	$(DUB) --compiler=dmd --config=sdp-dmd-debug-unittest
dmd_debug_clean: tangle
	$(DUB) --compiler=dmd --config=sdp-debug-clean
dmd_debug_src:
	$(DUB) --compiler=dmd --config=sdp-debug
# gdc
gdc_release: expunge skel tangle
	$(DUB) --compiler=gdc --config=sdp-release
gdc_release_stamp:
	$(DUB) --compiler=gdc --config=sdp-gdc
gdc_release_stamp_version:
	$(DUB) --compiler=gdc --config=sdp-gdc
	mv bin/sdp-gdc bin/sdp-gdc-$(PROJECT_VERSION)
gdc_release_tangle: tangle
	$(DUB) --compiler=gdc --config=sdp-gdc
gdc_release_expunge_tangle: expunge skel tangle
	$(DUB) --compiler=gdc --config=sdp-gdc
gdc_debug:
	$(DUB) --compiler=gdc --config=sdp-gdc-debug
gdc_debug_tangle: tangle
	$(DUB) --compiler=gdc --config=sdp-gdc-debug
gdc_debug_docs: clean_docs tangle
	$(DUB) --compiler=gdc --config=sdp-gdc-debug-docs
gdc_debug_unittest: tangle
	$(DUB) --compiler=gdc --config=sdp-gdc-debug-unittest
gdc_debug_clean: tangle
	$(DUB) --compiler=gdc --config=sdp-debug-clean
gdc_debug_src:
	$(DUB) --compiler=gdc --config=sdp-debug
# ldc2
ldc_rel: expunge skel tangle
	$(DUB) --compiler=ldc2 --config=sdp-release
ldc_stamp:
	$(DUB) --compiler=ldc2 --config=sdp-ldc
ldc_ver:
	$(DUB) --compiler=ldc2 --config=sdp-ldc
	mv bin/sdp-ldc bin/sdp-ldc-$(PROJECT_VERSION)
ldc_release: expunge skel tangle
	$(DUB) --compiler=ldc2 --config=sdp-release
ldc_release_stamp:
	$(DUB) --compiler=ldc2 --config=sdp-ldc
ldc_release_stamp_version:
	$(DUB) --compiler=ldc2 --config=sdp-ldc
	mv bin/sdp-ldc bin/sdp-ldc-$(PROJECT_VERSION)
ldc_release_tangle: tangle
	$(DUB) --compiler=ldc2 --config=sdp-ldc
ldc_release_expunge_tangle: expunge skel tangle
	$(DUB) --compiler=ldc2 --config=sdp-ldc
ldc_debug:
	$(DUB) --compiler=ldc2 --config=sdp-ldc-debug
ldc_debug_tangle: tangle
	$(DUB) --compiler=ldc2 --config=sdp-ldc-debug
ldc_debug_docs: clean_docs tangle
	$(DUB) --compiler=ldc2 --config=sdp-ldc-debug-docs
ldc_debug_unittest: tangle
	$(DUB) --compiler=ldc2 --config=sdp-ldc-debug-unittest
ldc_debug_clean: tangle
	$(DUB) --compiler=ldc2 --config=sdp-debug-clean
ldc_debug_src:
	$(DUB) --compiler=ldc2 --config=sdp-debug
dmd_release_test: tangle dmd_test_release
ldc_release_test: tangle ldc_test_release
rdmd: $(PRG_SRCDIR)/$(PRG_SRC)
	$(RDMD) $(RDMD_FLAGS)$(DC) $(DC_FLAGS) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_NAME)/$(PRG_SRC)
debug: $(PRG_SRCDIR)/$(PRG_SRC)
	$(DC) $(DC_FLAGS) $(DC_FLAGS_DEBUG) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)

debug_dmd: $(PRG_SRCDIR)/$(PRG_SRC)
	$(DMD) $(DMD_FLAGS) $(DMD_FLAGS_DEBUG) \
	$(DMD_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)

debug_ldc: $(PRG_SRCDIR)/$(PRG_SRC)
	$(LDC) $(LDC_FLAGS) $(LDC_FLAGS_DEBUG) \
	$(LDC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)

debug_gdc: $(PRG_SRCDIR)/$(PRG_SRC)
	$(GDC) $(GDC_FLAGS) $(GDC_FLAGS_DEBUG) \
	$(GDC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)
debug_rdmd: $(PRG_SRCDIR)/$(PRG_SRC)
	$(RDMD) $(RDMD_FLAGS)$(DC) $(DC_FLAGS) $(DC_FLAGS_DEBUG) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_NAME)/$(PRG_SRC)

debug_rdmd_dmd: $(PRG_SRCDIR)/$(PRG_SRC)
	$(RDMD) $(RDMD_FLAGS)$(DMD) $(DC_FLAGS) $(DC_FLAGS_DEBUG) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_NAME)/$(PRG_SRC)

debug_rdmd_ldc: $(PRG_SRCDIR)/$(PRG_SRC)
	$(RDMD) $(RDMD_FLAGS)$(LDC) $(DC_FLAGS) $(LDC_FLAGS_DEBUG) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_NAME)/$(PRG_SRC)

debug_rdmd_gdc: $(PRG_SRCDIR)/$(PRG_SRC)
	$(RDMD) $(RDMD_FLAGS)$(GDC) $(DC_FLAGS) $(GDC_FLAGS_DEBUG) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_NAME)/$(PRG_SRC)
release: distclean tangle $(PRG_SRCDIR)/$(PRG_SRC)
	$(DC) $(DC_FLAGS) $(DC_FLAGS_RELEASE) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)
release_rdmd: distclean tangle $(PRG_SRCDIR)/$(PRG_SRC)
	$(RDMD) $(RDMD_FLAGS)$(DC) $(DC_FLAGS) $(DC_FLAGS_RELEASE) \
	$(DC_FLAG_BINOF)$(PRG_BINDIR)/$(PRG_BIN) \
	$(PRG_SRCDIR)/$(PRG_SRC)
skel:
	mkdir -p $(PRG_SRCDIR)/$(PRG_NAME)/meta; \
	mkdir -p $(PRG_SRCDIR)/$(PRG_NAME)/conf; \
	mkdir -p $(PRG_SRCDIR)/$(PRG_NAME)/output; \
	mkdir -p $(PRG_SRCDIR)/$(PRG_NAME); \
	mkdir -p $(PRG_BINDIR);

init: skel

clean:
	rm -rf $(PRG_SRCDIR); \
	rm -rf $(PRG_DOCDIR);

clean_bin:
	rm $(PRG_BINDIR)/*

clean_src:
	rm -rf $(PRG_SRCDIR);

clean_docs:
	rm -rf $(PRG_DOCDIR)

expunge:
	rm -f dub.selections.json; \
	rm -rf $(PRG_SRCDIR); \
	rm -rf $(PRG_BINDIR); \
	rm -rf $(PRG_DOCDIR);

distclean: expunge

distclean_and_init: expunge
	mkdir -p $(PRG_SRCDIR)/$(PRG_NAME); \
	mkdir -p $(PRG_BINDIR);
tangle: skel
	for f in $(ORGFILELIST); do \
		ORGFILES="$$ORGFILES \"$$f\""; \
	done; \
	emacs --batch -Q -q \
	--eval "(progn \
		(add-to-list 'load-path \
			(expand-file-name \"$(EMACSLISP)\")) \
		(add-to-list 'load-path \
			(expand-file-name \"$(EMACSLISP_ORG)\" t)) \
		(add-to-list 'load-path \
			(expand-file-name \"$(EMACSLISP_ORG_CONTRIB)\" t)) \
		(require 'org)(require 'ob)(require 'ob-tangle) \
		(mapc (lambda (file) \
			(find-file (expand-file-name file \"$(ORGDIR)\")) \
				(setq-local org-src-preserve-indentation t) \
			(org-babel-tangle) \
			(kill-buffer)) '($$ORGFILES)))" 2>&1
tangle_maker:
	for f in $(ORGFILELIST); do \
		ORGFILES="\"maker.org\""; \
	done; \
	emacs --batch -Q -q \
	--eval "(progn \
		(add-to-list 'load-path \
			(expand-file-name \"$(EMACSLISP)\")) \
		(add-to-list 'load-path \
			(expand-file-name \"$(EMACSLISP_ORG)\" t)) \
		(add-to-list 'load-path \
			(expand-file-name \"$(EMACSLISP_ORG_CONTRIB)\" t)) \
		(require 'org)(require 'ob)(require 'ob-tangle) \
		(mapc (lambda (file) \
			(find-file (expand-file-name file \".\")) \
				(setq-local org-src-preserve-indentation t) \
			(org-babel-tangle) \
			(kill-buffer)) '($$ORGFILES)))" 2>&1
gitsnapshot: distclean tangle
	git commit -a
.PHONY : all build rebuild debug release \
	distclean init \
	tangle gitsnapshot