###############################################################################
#                                                                             #
#  Smart makefile                                                             #
#                                                                             #
#  1) Call "make depend" so if you change any source or header files, it      #
#     will be detected and the appropriate files will be recompiled.          #
#                                                                             #
#  2) Run "make" with any flags you wish to use.                              #
#                                                                             #
#  3) If you create new header files that aren't being properly compiled in   #
#     with the rest of the project, you can just re-run "make depend" to      #
#     generate the dependencies.                                              #
#                                                                             #
#  4) The only drawback is that if you have any files you want to EXCLUDE,    #
#     or INCLUDE from a directory other than under SRC_PATH, you may have to  #
#     modify this makefile a bit to work with those files.                    #
#                                                                             #
###############################################################################

.PHONY: all clean distclean depend


###############################################################################
#                                                                             #
#  NAME_BIN: Filename for the executable                                      #
#                                                                             #
###############################################################################

NAME_BIN=test


###############################################################################
#                                                                             #
#  DIR_*: Path (relative to this makefile) where the files can/will be found  #
#         BIN_PATH: generated program binary                                  #
#         OBJ_PATH: generated object files                                    #
#         SRC_PATH: source directory                                          #
#         INC_PATH: header file included from the sources                     #
#                                                                             #
###############################################################################

BIN_PATH=./bin
OBJ_PATH=./obj
SRC_PATH=./src
INC_PATH=./include


###############################################################################
#                                                                             #
#  SFX_*: Suffixes for executable, object files, source files, header files   #
#                                                                             #
###############################################################################

BIN_SUFFIX=
OBJ_SUFFIX=.o
CPP_SRC_SUFFIX=.cpp
HDR_SUFFIX=.h


###############################################################################
#                                                                             #
#  CPP_SOURCE_FILES: Name of each of the .cpp files found under ./src         #
#  HEADER_FILES: Name of each of the .h files found under ./include           #
#                                                                             #
#  BIN: full path and filename for the binary: ./bin/run_me.exe               #
#                                                                             #
#  CPP_OBJECTS: full path and filename for each of generated object files     #
#  INCLUDES: full path and filename for each ./include/*.h file located       #
#                                                                             #
###############################################################################

CPP_SOURCE_FILES=$(notdir $(basename $(wildcard $(SRC_PATH)/*$(CPP_SRC_SUFFIX))))
HEADER_FILES=$(notdir $(basename $(wildcard $(HDR_PATH)/*$(HDR_SUFFIX))))

BIN=$(BIN_PATH)/$(NAME_BIN)$(BIN_SUFFIX)

CPP_OBJECTS =$(addprefix $(OBJ_PATH)/, $(addsuffix $(OBJ_SUFFIX), $(basename $(CPP_SOURCE_FILES))))
INCLUDES=$(addprefix $(INC_PATH)/, $(addsuffix $(HDR_SUFFIX), $(basename $(HEADER_FILES))))

DEPEND=$(OBJ_PATH)/makefile.dep


###############################################################################
#                                                                             #
#  Specify the compiler, "clean" remover, and flags related to them           #
#                                                                             #
###############################################################################

CC=g++

CFLAGS=-c -W -Wall -Wno-unused -g3 -ggdb3 -O0 -DDEBUG -I$(INC_PATH)
LDFLAGS=-W -Wall -g3 -ggdb3 -O0

### Profiling
#CFLAGS+=-pg
#LDFLAGS+=-pg

RM=rm
RMFLAGS=-rf
DEPFLAGS=-MM -MG -I$(INC_PATH)


### For Macs (and Linux?)
LIBS=`allegro-config --libs debug`

### For Windows
#LIBS=-lalld -lwinmm


###############################################################################
#                                                                             #
#  clean: deletes the executable and object files                             #
#  distclean: runs "clean" and also deletes generated dependency file(s),     #
#             "./obj/makefile.dep"                                            #
#                                                                             #
###############################################################################

$(BIN): $(CPP_OBJECTS)
	$(CC) -o "$(BIN)" $(LDFLAGS) $(CPP_OBJECTS) $(COMPILER_FLAGS) $(LIBS)


$(OBJ_PATH)/%$(OBJ_SUFFIX) : $(SRC_PATH)/%$(CPP_SRC_SUFFIX)
	$(COMPILE.c) -o $@ $<

$(CPP_OBJECTS): $(INCLUDES)
	$(CC) -o "$@" $(CFLAGS) $(addprefix $(SRC_PATH)/, $(notdir $(addsuffix $(CPP_SRC_SUFFIX), $(basename $@))))


all: $(BIN)


clean:
	@echo Removing binary and generated object files
	$(RM) $(RMFLAGS) $(BIN) $(OBJ_PATH)/*$(OBJ_SUFFIX)


distclean: clean
	@echo Also removing dependency file "$(DEPEND)" and debugging/profiling files
	$(RM) $(RMFLAGS) $(DEPEND) gmon.out allegro.log


###############################################################################
#                                                                             #
#  We use "sed" to prepend the path to the object directory, and tack on the  #
#  appropriate object-file suffix (".o" or whatever).  This means that if     #
#  OBJ_SUFFIX or OBJ_PATH ever change, the dependencies file will still work  #
#  properly.  It also flips the "/" to "\" in the pathnames as desired for    #
#  use with the current system.                                               #
#                                                                             #
###############################################################################

depend:
	$(CC) $(DEPFLAGS) $(SRC_PATH)/*$(CPP_SRC_SUFFIX) > _depend.tmp
	sed -e "s/^\([a-zA-Z0-9_]*\)\$(OBJ_SUFFIX):/$(subst /,\/,$(OBJ_PATH))\/\1\$(OBJ_SUFFIX):/" _depend.tmp > $(DEPEND)
	$(RM) $(RMFLAGS) _depend.tmp


###############################################################################
#                                                                             #
#  If you change any of the sources or #include header files, they will only  #
#  be detected as changed if you have first run "make depend".  If you don't  #
#  run that first, this script doesn't notice changes to those files.         #
#                                                                             #
#  However, once created (it will be called "./obj/makefile.dep"), changing   #
#  a src/*.cpp file will cause that single file to recompile, and changing    #
#  an "./include/*.h" file will cause everything linked to that header file   #
#  to be recompiled.                                                          #
#                                                                             #
#  It's important that the following line has the "-" before it, so if the    #
#  "./obj/makefile.dep" file is NOT found, it won't stop with warnings: it    #
#  will simply continue silently.                                             #
#                                                                             #
###############################################################################

-include $(DEPEND)
