Using make and writing Makefiles
--------------------------------
make is a Unix tool to simplify building program executables from many 
modules.  make reads in rules (specified as a list of target entries)
from a user created Makefile.  make will only re-build things that 
need to be re-built (object or executables that depend on files that 
have been modified since the last time the objects or executables were
built).  

Using make
----------
(1) Create a Makefile listing the rules for building the executable the 
    file should be named 'Makefile' or 'makefile'.  This only has to 
    be done once, except when new modules are added to the program, the 
    Makefile must be updated to add new module dependencies to existing 
    rules and to add new rules to build the new modules.

(2) After editing program file(s), rebuild the executable by typing make:
	% make 

    A specific target in the Makefile can be executed by typing:
	% make target_label

    For example, to execute the rm commands in the example makefile 
    below, type:
	% make clean

Creating a Makefile
-------------------
A Makefile typically starts with some variable definitions which are
then followed by a set of target entries for building specific targets 
(typically .o & executable files) or executing a set of command 
associated with a target label.  

The following is the generic target entry form: 

# comment
# (note: the <tab> in the command line is necessary for make to work) 
target:  dependency1 dependency2 ...
      <tab> command

for example:
#
# target entry to build program executable from program and mylib 
# object files 
#
program: program.o mylib.o
	gccx -o program program.o mylib.o


An example Makefile
-------------------
#
# This is an example Makefile for a countwords program.  This
# program uses both the scanner module and a counter module.
# Typing 'make' or 'make count' will create the executable file.
#

# define some Makefile variables for the compiler and compiler flags
# to use Makefile variables later in the Makefile: $(<var_name>)
#   -g    adds debugging information to a.out file
#   -Wall turns on most (but not all) compiler warnings 
#
CC = gcc
CFLAGS  = -g -Wall

# typing 'make' will invoke the first target entry in the file 
# (in this case the default target entry)
#
default: count

# To create the executable file count we need the object files
# countwords.o, counter.o, and scanner.o:
#
count:          countwords.o counter.o scanner.o
		$(CC) $(CFLAGS) -o count countwords.o counter.o scanner.o

# To create the object file countwords.o, we need the source
# files countwords.c, scanner.h, and counter.h:
#
countwords.o:   countwords.c scanner.h counter.h
                $(CC) $(CFLAGS) -c countwords.c

# To create the object file counter.o, we need the source files
# counter.c and counter.h:
#
counter.o:      counter.c counter.h
                $(CC) $(CFLAGS) -c counter.c

# To create the object file scanner.o, we need the source files
# scanner.c and scanner.h:
#
scanner.o:      scanner.c scanner.h
                $(CC) $(CFLAGS) -c scanner.c

# To start over from scratch, type 'make clean'.  This
# removes the executable file, as well as old .o object
# files and *~ backup files:
#
clean:
                rm -f count *.o *~

