#
# Small Project Makefile
#
# this file is small a part of build_process package.
# full-featured build_process is available on BSD license
# on http://www.baszerr.org, prjs -> build_process.
#


ifeq (,$(filter %/gen/$(TARGET),$(basename $(CURDIR))))
#
# main part, run in sources dir
#

# don't use Verbose mode (be silent)?
ifeq (,$V)
MFLAGS+=-s
endif

define run-in-gen
	@echo
	@echo "##### build $@"
	mkdir -p "$(GENDIR)/$@" \
	          `find . -type d | grep -v './\.' | \
	          grep -v '^\./gen/' | grep -v '^\./gen$$' | \
			  grep -v '^\.$$' | sed 's:^\./:$(GENDIR)/$@/:'`
	+$(MAKE) $(MFLAGS) -C "$(GENDIR)/$@" -f "$(CURDIR)/Makefile" \
		TARGET=$@ $(TARGET)
endef

.SUFFIXES:

# use user-provided configuration
include config.mk

GENDIR:=$(CURDIR)/gen
SRCDIR:=$(CURDIR)
VPATH+=$(SRCDIR)
export GENDIR SRCDIR VPATH


CXXSRCS_NOMAIN:=$(shell find . -iname '*.cpp' -exec grep -L '^int main' {} \; )

export CSRCS_NOMAIN CXXSRCS_NOMAIN
CXXTESTSRCS:=$(shell ls ./src/*.t.cpp ./src/*/*.t.cpp)

export CTESTSRCS CXXTESTSRCS

BENCHCXXSRCS:=$(filter-out $(CXXTESTSRCS), $(shell ls ./src/*.cpp | grep -v nchr2.cpp | grep -v API; ls ./src/detail/*.cpp))

export BENCHCSRCS BENCHCXXSRCS

CXXSRCS:=$(filter-out $(CXXTESTSRCS), $(shell find . -iname '*.cpp' | grep -v bench.cpp))

export CSRCS CXXSRCS

COMMON_FLAGS:=-Wall -I$(SRCDIR)

CXXFLAGS+=$(COMMON_FLAGS)
export CXXFLAGS

LDFLAGS+=
export LDFLAGS

export TARGET

TEST_PROGRAM_NAME=$(PROGRAM_NAME).t
export TEST_PROGRAM_NAME

BENCH_PROGRAM_NAME=bench.out
export BENCH_PROGRAM_NAME


.PHONY: all
all: debug


.PHONY: debug
debug: CXXFLAGS+=-g3
debug: TARGET:=all
debug:
	@$(run-in-gen)
	beep 2>/dev/null

.PHONY: release
release: CXXFLAGS+=-O3 -g -DNDEBUG
release: TARGET:=all
release:
	@$(run-in-gen)
	beep 2>/dev/null

.PHONY: profile
profile: CXXFLAGS+=-pg -DNDEBUG -O3 -g
profile: LDFLAGS+=-pg
profile: TARGET:=all
profile:
	@$(run-in-gen)
	beep 2>/dev/null

.PHONY: test
test: CXXFLAGS+=-g3 -O0
test: TARGET:=test
test:
	@$(run-in-gen)
	beep 2>/dev/null

.PHONY: doc
doc:
	@echo
	@echo "##### clean"
	mkdir -p gen
	doxygen src/doxy


.PHONY: bench
bench: CXXFLAGS+=-O3 -g -DNDEBUG
bench: TARGET:=bench
bench:
	@$(run-in-gen)
	beep 2>/dev/null


.PHONY: clean
clean:
	@echo
	@echo "##### clean"
	rm -rf "$(GENDIR)"

else
#
# part run in gen
#

# object files:
CXXOBJS+=$(CXXSRCS:.cpp=.o)
# obj files without 'main()':
CXXOBJS_NOMAIN+=$(CXXSRCS_NOMAIN:.cpp=.o)
# test object files:
CXXTESTOBJS+=$(CXXTESTSRCS:.cpp=.o)

# bench object files:
BENCHCXXOBJS+=$(BENCHCXXSRCS:.cpp=.o)


# dep files:
CXXDEPS +=$(CXXSRCS:.cpp=.d) $(CXXTESTSRCS:.cpp=.d) $(BENCHCXXTESTSRCS:.cpp=.d)


.PHONY: all
all: $(PROGRAM_NAME)

.PHONY: test
test: $(TEST_PROGRAM_NAME)

.PHONY: bench
bench: $(BENCH_PROGRAM_NAME)

$(TEST_PROGRAM_NAME): $(CXXTESTOBJS) $(CXXOBJS_NOMAIN)
	echo "LD  $@"
	$(LD) $(LDFLAGS) -o $@ $^

$(PROGRAM_NAME): $(CXXOBJS) $(COBJS)
	echo "LD  $@"
	$(LD) $(LDFLAGS) -o $@ $^

$(BENCH_PROGRAM_NAME): $(BENCHCXXOBJS)
	echo "LD  $@"
	$(LD) $(LDFLAGS) -o $@ $^


# C++ source files:
%.o: %.cpp $(SRCDIR)/Makefile
	echo "CXX $*.cpp"
	$(CXX) $(CXXFLAGS) -MMD -c "$(SRCDIR)/$*.cpp" -o "$@"

# makefile depends on its include
$(SRCDIR)/Makefile: $(SRCDIR)/config.mk
	touch "$@"

# has C sources?
-include $(CDEPS)

# has C++ sources?
-include $(CXXDEPS)

endif
