# Lightweight & simple Makefile - build 110128
# 2011 (C) Donjan Rodic - for free use
#
# Requires all source files & headers to be in one directory (SOURCEDIR)
# Produces one binary (BINDIR/BINARY)
#
# usage: make [ all | OBJ | debug | clean | install | uninstall | info ]
#  where OBJ is the path to an object file
# example: make
#          make install
#
################################################################################
# Config

# The directories (except SOURCEDIR & INFODIR) will be generated if not existing
SOURCEDIR = src
OBJDIR = objs
BINDIR = bin
BINARY = YOUR_PROGRAM_NAME
DESTDIR = ./
INFODIR = doc

# Path to headers for which (when changed) all objects should be recompiled
# Required if there is no source file with the same basename
SHAREDHEADERS =

# Only one SOURCEEXT is supported, but as many HEADEREXT as you wish
SOURCEEXT = cpp
HEADEREXT = h hpp hxx

CC = g++
CFLAGS = -Wall -Wextra -Werror -pedantic-errors -ansi -O2
DBGFLAGS = -Wall -Wextra -Werror -pedantic-errors -ansi -O0 -g3 -pg -rdynamic
LIBS = 

SMART_MKDIR = mkdir -p
SHELL = /bin/sh


################################################################################
# Automation starts here
# When trying to improve, don't remove "superfluous" code... it's needed!

.PHONY: all debug clean install uninstall info

BIN = $(BINDIR)/$(BINARY)
DESTBIN = $(DESTDIR)/$(BINARY)
VPATH = $(SOURCEDIR)
SOURCES=$(wildcard $(SOURCEDIR)/*.$(SOURCEEXT))
OBJS=$(subst $(SOURCEDIR),$(OBJDIR),$(SOURCES:.$(SOURCEEXT)=.o))
HEADERS:=$(foreach EXT,$(HEADEREXT), $(wildcard $(SOURCEDIR)/*.$(EXT)) )
HEADER_WITH_OBJ:=$(foreach FILE,$(HEADERS), \
$(if $(wildcard $(addsuffix .$(SOURCEEXT),$(basename $(FILE)) )), $(FILE)) \
)

all: $(BIN)

$(BIN): $(SHAREDHEADERS) $(OBJS)
	@$(SMART_MKDIR) $(BINDIR)
	$(CC) $(CFLAGS) -o $(BIN) $(OBJS) $(LIBS)
	@echo Shared headers are: $(SHAREDHEADERS)

$(OBJDIR)/%.o: %.$(SOURCEEXT) $(SHAREDHEADERS)
	@$(SMART_MKDIR) $(OBJDIR)
	$(CC) $(CFLAGS) -c $< -o $@

# Workaround: adds trigger on headers modification (obj.o: obj.HEADEREXT)
$(foreach FILE,$(HEADER_WITH_OBJ),$(eval \
$(subst $(SOURCEDIR), $(OBJDIR), $(addsuffix .o,$(basename $(FILE)) )): $(FILE)\
))


debug: $(SOURCES) $(HEADERS) $(SHAREDHEADERS)
	$(CC) $(DBGFLAGS) -o $(BIN)-dbg $(SOURCES) $(LIBS)

clean:
	rm -f $(BIN)
	rm -f $(BIN)-dbg
	rm -f $(BINDIR)/gmon.out
	rm -f $(OBJS)
	rm -rf $(OBJDIR)

install: $(BIN)
	@$(SMART_MKDIR) $(DESTDIR)
	cp $(BIN) $(DESTBIN)

uninstall: $(DESTBIN)
	rm $(DESTBIN)

info:
	cd $(INFODIR) && $(MAKE)
