# Last updated: 13 Oct 2019 (changes below)
#
# Makefile to automagically generate dependencies for each C file in current
# working directory. Simply run `make depend' and after that whenever you run
# `make' only source files that have been updated (or dependencies have been
# updated) will be recompiled.
#
# Note that inaccurate dependencies can cause a variety of problems! I wrote
# about this very problem (and I link to this Makefile from it):
#    https://texts.xexyl.net/docs/c-function-prototypes-dependencies.txt
#
# What this really means is whenever you #include another file run
# `make depend'.  Note that the -MM option only creates dependencies for
# non-system header files i.e. header files that are part of a non-standard
# project. If you want it to generate for system header files to you can change
# the '-MM' below to simply '-M'.
#
# This Makefile is adapted from a set of Makefiles created by a good friend
# Martijn Schoemaker (Link: https://ficture.nl [in Dutch]) as part of a project
# he and I have been involved in for years (his project and I came in quite some
# years later); there are three differences in this Makefile that `make' it
# 'special':
#
# 	1. Instead of being a Makefile for a single program with multiple
# 	   objects compiled and linked into the executable it compiles multiple
# 	   independent programs one after another.
#
# 	2. With some pattern and (admittedly simple) regular expression magic
# 	   this Makefile doesn't need to know what source files exist; it
# 	   determines this on its own.
#
#	3. Finally the make depend target also updates any .gitignore file (in
#	   the working directory only!) to add the name of binary files that
#	   would be compiled from the source files by running make.
#
# The real benefit is the magic behind it all: you can generate dependencies for
# all individual source files in the current working directory simply by running
# `make depend' and then when you run `make' it'll only recompile those that
# need recompilation (it'll also compile files that haven't been). Do note that
# if there is a compilation/linker error it'll stop the entire process; fix the
# error(s) and try again.
#
# [You don't technically have to have dependencies generated but having
# dependencies - even if no #included files - allows `make' to only (re)compile
# source files that need to be. This is more useful in large projects - to save
# time - but there is also no need to recompile programs/objects that have no
# source code updates.]
#
# I would really appreciate it that you keep this Makefile intact (that is these
# comments) but otherwise it is in the public domain: use however and whenever
# you want/need/like an automagically dependency updating Makefile.
#
#
# Last updated: 13 October 2019
# -- Xexyl (aka Cody)
#
# Makefile history
#
#   * 13 Oct 2019
#   - Add helper script 'make-gitignore.sh' for make depend target depend: make
#     depend now updates .gitignore file to exclude the names of the binary
#     files in this Makefile.
#
#
#   * 12 September 2019
#   - Clean up Makefile (it now works under both macOS and Linux by using
#     features of Makefiles directly).
#   - Remove -g from CFLAGS (still have -Wall because warnings are a
#     programmer's friend).
#   - Remove -v from rm invocation.
#
#
#   * 11 Sep 2019
#   - Reduced the for loops in targets 'default' and 'clean' to simply be an
#     'echo'.
#   - Add note below about file names which have spaces etc. in them.
#
#
#   * 23 Apr 2019
#   - Original file.

# You can change the CFLAGS, LDFLAGS, CC and MAKE where necessary/applicable but
# anything below you probably shouldn't change unless you know what you're doing
# or are doing some experiment.

CFLAGS=-Wall
LDFLAGS=-lm
CC=gcc
MAKE=make

# XXX that if any of the source files have spaces or even newlines in the name
# it will break the Makefile when running `make depend`. Be that as it may I
# hope that anyone who `make`s use of this is not so silly as to have such file
# names! :)
OBJFILES = *.o
SRCFILES = $(patsubst %.o,%.c,$(OBJFILES))
BINFILES = $(patsubst %.c,%,$(wildcard *.c))

default: ${SRCFILES}
	@${MAKE} ${BINFILES}

clean:
	@rm -f ${BINFILES}
	@echo Removed binary files.

depend:
	@LINE="`grep -n '^### AUTOMAGICALLY GENERATED DEPENDENCIES' Makefile|cut -d: -f1-1`";	\
	if [ "$$LINE" = "" ]; then								\
		echo "Make depend aborted, tag not found in Makefile.";				\
		exit;										\
	fi;											\
	mv -f Makefile Makefile.orig;head -n $$LINE Makefile.orig > Makefile;			\
	echo "Generating dependencies.";							\
	${CC} ${CFLAGS} -MM ${SRCFILES} | sed -e 's/\.o//g' >> Makefile;			\
	$(MAKE) gitignore
	@echo "Make depend completed."

gitignore:
	@echo "Regenerating .gitignore";							\
	chmod +x make-gitignore.sh;								\
	./make-gitignore.sh;									\
	echo "Done."

### AUTOMAGICALLY GENERATED DEPENDENCIES BELOW
func: func.c
function: function.c
test: test.c test.h
test2: test2.c
