# BUILD CONFIGURATION ---------------------------------------------------------
# Note that BINARY here acts as a _prefix_ for the -nc and -gtk versions.
BINARY   = freechain
VERSION  = 0.6
SCRATCH  = /tmp/scratch/$(BINARY)/
DISTFILE = freechain-$(VERSION).zip
DISTMSG  = "FreeChain version $(VERSION)"

# expects GNU-flavoured tools
    CC = gcc
    LD = gcc
   ZIP = zip
 UNZIP = unzip
    SH = bash
  ECHO = echo
PRINTF = printf
    RM = rm
 MKDIR = mkdir
 RMDIR = rmdir
    CP = cp
    MV = mv
 EGREP = egrep
PKGCNF = pkg-config

# Extra flags to control build type
# Debugging:
# CFLAGSEX = -g -O
#LDFLAGSEX =
# Release:
# CFLAGSEX = -O3 -Werror
#LDFLAGSEX =
# Release (Cygwin):
 CFLAGSEX = -O3 -Werror -mno-cygwin -I/usr/include/ -I/usr/include/ncurses/
LDFLAGSEX = -mno-cygin -L/usr/lib/ncurses/

# Directories for objects (used to select appropriate compile/link flags)
OBJDIRANY = objs-any
OBJDIRNC  = objs-nc
OBJDIRGTK = objs-gtk

# SOURCES ---------------------------------------------------------------------
    SRCANY = game.c aiminimax.c simulate.c
    SRCNC  = ncurses.c ncursessetup.c
    SRCGTK = gtkui.c gtkgrid.c gtkplayer.c gtkloader.c gtksetup.c
  CSOURCES = $(SRCANY) $(SRCNC) $(SRCGTK)
   HEADERS = game.h ui.h ai.h simulate.h \
             ncursesui.h \
             gtkgrid.h gtkplayer.h gtkloader.h gtksetup.h
 EXTRADIST = Makefile README.txt CHANGELOG.txt LICENSE.txt gtkui.glade \
             doshacks.h pstdint.h compile.bat
# DOS stuff goes in EXTRADIST, not HEADERS, because Linux build is ignorant
# of it.

# PREAMBLE / AUTOCONFIGURATION / DERIVED --------------------------------------
BINARIES = $(BINARY)-nc $(BINARY)-gtk
OBJECTSANY = $(SRCANY:%.c=$(OBJDIRANY)/%.o)
OBJECTSNC  =  $(SRCNC:%.c=$(OBJDIRNC)/%.o)
OBJECTSGTK = $(SRCGTK:%.c=$(OBJDIRGTK)/%.o)
OBJECTS = $(OBJECTSANY) $(OBJECTSNC) $(OBJECTSGTK)
NOTOBJECTS = $(filter-out %.o, $(OBJECTS))
ifneq ($(NOTOBJECTS),)
    $(error OBJECTS contains non-object(s) $(NOTOBJECTS))
endif
SOURCES = $(CSOURCES)
OBJDIRS = $(OBJDIRANY) $(OBJDIRNC) $(OBJDIRGTK)

# All files which are sources, /including/ non-compiled ones (e.g. headers)
ALLSOURCESMANU = $(SOURCES) $(HEADERS)

# Compiler warning flags (-Werror is saved for release build)
WARNFLAGS = -W -Wall -Wpointer-arith -Wcast-align -Wwrite-strings \
            -Wno-unused-parameter -Wuninitialized -Wno-unknown-pragmas
CWFLAGS   = $(WARNFLAGS) -Wcast-qual -Wmissing-declarations \
            -Wnested-externs -Wredundant-decls -Wundef \
            -Wstrict-prototypes -Wmissing-prototypes

# Tool flags
CFLAGS     = -I./ -I./src -std=c99 -pedantic -DVERSION='"$(VERSION)"' \
             $(CWFLAGS) $(CFLAGSEX)
CFLAGSNC   = $(CFLAGS)
CFLAGSGTK  = $(CFLAGS)  $(shell $(PKGCNF) --cflags gtk+-2.0 libglade-2.0) \
             -Wno-strict-prototypes
LDFLAGS    = $(LDFLAGSEX)
LDFLAGSNC  = $(LDFLAGS) -lncurses
LDFLAGSGTK = $(LDFLAGS) $(shell $(PKGCNF) --libs   gtk+-2.0 libglade-2.0)

EXTRACDEPS = Makefile $(HEADERS)

# MAKEFILE METADATA AND MISCELLANY --------------------------------------------
# Gratuitous colours. While they make your build process look like an
# '80s disco, they also make it easy to see what it's doing at-a-glance.
RED=\033[31;1m
YELLOW=\033[33;1m
GREEN=\033[32;1m
BLUE=\033[34;1m
MAGENTA=\033[35;1m
CYAN=\033[36;1m
WHITE=\033[0m
RV=\033[7m
COLUMN2=\033[40G

.PHONY: all prepare clean dist disttest work env info

# RULES =======================================================================
all: prepare $(BINARIES)

prepare:
	@$(MKDIR) -p $(OBJDIRS)

$(BINARY)-nc: $(OBJECTSANY) $(OBJECTSNC)
	@$(PRINTF) "$(BLUE)--- $(RV)LINKING   $(WHITE) $@\n"
	@$(LD) -o $(BINARY)-nc $^ $(LDFLAGSNC)
	@$(PRINTF) "$(BLUE)$(RV)***$(WHITE) $(BINARY)-nc built\n"

$(BINARY)-gtk: $(OBJECTSANY) $(OBJECTSGTK)
	@$(PRINTF) "$(BLUE)--- $(RV)LINKING   $(WHITE) $@\n"
	@$(LD) $(LDFLAGSGTK) -o $(BINARY)-gtk $^
	@$(PRINTF) "$(BLUE)$(RV)***$(WHITE) $(BINARY)-gtk built\n"

$(OBJDIRANY)/%.o : %.c $(EXTRACDEPS)
	@$(PRINTF) "$(GREEN)--- $(RV)COMPILING $(WHITE) $<\n"
	@$(CC) -o $@ -c $(CFLAGS)    $<

$(OBJDIRNC)/%.o  : %.c $(EXTRACDEPS)
	@$(PRINTF) "$(GREEN)--- $(RV)COMPILING $(WHITE) $<\n"
	@$(CC) -o $@ -c $(CFLAGSNC)  $<

$(OBJDIRGTK)/%.o : %.c $(EXTRACDEPS)
	@$(PRINTF) "$(GREEN)--- $(RV)COMPILING $(WHITE) $<\n"
	@$(CC) -o $@ -c $(CFLAGSGTK) $<

clean:
	@$(PRINTF) "$(RED)--- $(RV)CLEANING  $(WHITE)\n"
	@$(RM) -fv  $(OBJECTS)
	@$(RMDIR) $(OBJDIRS)
	@$(RM) -fvr $(SCRATCH)
	@$(RM) -fv  $(BINARIES) $(DISTFILE)
	@$(PRINTF) "$(RED)$(RV)***$(WHITE) Cleansed\n"

# Create distributable archive
dist: $(DISTFILE)
$(DISTFILE): $(SOURCES) $(HEADERS) $(EXTRADIST)
	@$(PRINTF) "$(MAGENTA)--- $(RV)BUNDLING  $(WHITE) $(DISTFILE)\n"
	@$(ECHO) $(DISTMSG) | $(ZIP) -z -9 $(DISTFILE) $^
	@$(PRINTF) "$(MAGENTA)$(RV)***$(WHITE) $(DISTFILE) created\n"

# Test distributable
disttest: $(DISTFILE)
	@$(PRINTF) "$(CYAN)--- $(RV)TESTING   $(WHITE) $(DISTFILE)\n"
	@$(MKDIR) -p $(SCRATCH)
	@$(CP) $(DISTFILE) $(SCRATCH)
	@$(ECHO) "cd $(SCRATCH); $(UNZIP) $(DISTFILE); make" | $(SH)
	@$(PRINTF) "$(CYAN)$(RV)***$(WHITE) Distributable tested\n"

# To `make work' is to find things to do ;)
work: $(SOURCES) $(HEADERS)
	@$(PRINTF) "$(RV)***$(WHITE) Outstanding tasks:\n"
	@$(EGREP) '(\\todo|TODO|XXX|FIXME)' --color=auto $^ || true


# Build environment information
env:
	@$(PRINTF) "C compiler      : $(CC)\n"
	@$(PRINTF) "Linker          : $(LD)\n"
	@$(PRINTF) "C compile flags : $(CFLAGS)\n"
	@$(PRINTF) "         (GTK+) : $(CFLAGSGTK)\n"
	@$(PRINTF) "Linker flags    : $(LDFLAGS)\n"
	@$(PRINTF) "      (ncurses) : $(LDFLAGSNC)\n"
	@$(PRINTF) "         (GTK+) : $(LDFLAGSGTK)\n"

# Complete Makefile information
info: env
	@$(PRINTF) "C sources       : $(CSOURCES)\n"
	@$(PRINTF) "Objects         : $(OBJECTS)\n"

