#
#  E X A M P L E _ M A K E F I L E
#
#  Alexis Layton
#  Harvard Extension CSci-E26 Fall 2016
#
#  This makefile is an example for a small (single-directory) set of programs.
#  It is designed to work with the default GNUmake rules.
#
#  Makefiles can be named "makefile" but "Makefile" is often preferred because
#  it shows up earlier in the directory listing and can be easier to spot.
#  Only have one of these names.
#
#  In many cases the default rules in make mean you only have to specify
#  the link command and the object/source file dependencies.
#
#  General syntax:
#
#  Variables. By convention most make variable are all-caps.
#
#  VARIABLE = value
#
#  Line continuations require a backslash
#
#  VARIABLE = value1 \
#   	      value2
#
#  target: dep1 \
#    	   dep2
#
#  Rules.
#
#  target: dependency dependency2 ...
#	build script
#	more build script
#
#  IMPORTANT: the whitespace before a build script line must be a TAB
#  character.
#
#  The target is something which is constructed by the build_script whenever
#  any of the dependencies are newer than the target. A proper build script
#  ensures that the target exists if it was successful and does not exist
#  if it failed. The build scripts are shell commands. It's possible to have
#  more than one target but it is not common.
#
#  A given target can only have one explicit build script, but can appear
#  in several rules with dependencies. The dependencies for a target like
#  this are the union of all the dependencies specified in the make file.

#  If no build script is specified for a target in the makefile, make will
#  try to use a set of default rules. (You can do "make -n -p -f /dev/null"
#  to print the default rules (if you leave off the -f /dev/null it will
#  incorporate any explicit rules in the makefiles of the current directory).
#  Note the output is large, because make has defaults for quite a few
#  programming languages.)
#
#  Variable expansions are $(VARIABLE) or ${VARIABLE} unless variable is a
#  single letter, in which case $V works.
#
#  Special variables:
#    $@		The target of a rule
#    $<		The first dependency of a rule
#    $^		All the dependencies of a rule
#    $*		The basename (filename without extension) of $@


#  Here is a general template. Things which are commented out only need to
#  be used if necessary.


# The list of programs this file is responsible for
#
PROGRAMS = fred wilma

# C compiler
# The default value for the system is usually ok.
#
#CC=gcc

# C Compiler flags (optional but recommended)
#
CFLAGS = -g -Wall -Wextra -std=gnu99

# C Preprocessor Flags
# put -Dsymbol and -IincludePath switches here if needed
#
#CPPFLAGS = -DMY_COMPILE_FLAG

# Linker flags
# put -LlibraryPath flags and -Wl... flags here
#
#LDFLAGS =

# Libraries
# put -llibName flags here
#
#LOADLIBES =

# The default rule
#
# This needs to be the first rule in the makefile, or you can set
#.DEFAULT_GOAL := all
#
all: $(PROGRAMS)

# What comprises the fred program
#
fred: fred.o barney.o dino.o
	$(LINK.c) $^ -o $@

# What comprises the wilma program
#
wilma: wilma.o betty.o bambam.o
	$(LINK.c) $^ -o $@

# Object file dependencies
#
# If you have header files, it is necessary to have each object file
# (not source file) depend on the header files it includes, directly
# or indirectly. This can be automated but it makes the makefile much
# more complicated and a bit compiler-specific.
#
# Note the default dependency is x.o: x.c; if you add headers you need
# to be explicit.

# You also don't need to be explicit about how a .o file is made from a .c
# file, but the default build script is something like
#
#      $(COMPILE.c) $(OUTPUT_OPTION) $<
#
# which is why the .c file has to be the first one listed usually.

bambam.o: bambam.c bambam.h
barney.o: barney.c dino.h
betty.o: betty.c betty.h bambam.h
dino.o: dino.c dino.h
fred.o: fred.c barney.h dino.h
wilma.o: wilma.c wilma.h betty.h

# If you have a very long list of files, you can use the following syntax,
# which uses a make variable to hold a list of filenames:
PROG_OBJS = \
	object_file1.o \
	object_file2.o \
	object_file3.o \
	object_file4.o \
	object_file5.o

prog: $(PROG_OBJS)
	$(LINK.c) $^ -o $@

# The cleanup rule (the *.dSYM part is for Macintosh debugging info dirs,\
# it can be omitted on GNU/Linux systems)
#
clean:
	$(RM) -f $(PROGRAMS) *.o a.out
	$(RM) -rf *.dSYM
