An Introduction to Makefiles
	
	What the heck is a Makefile? (Isn't that two separate words?)
	
	Well, I'm glad you asked. No makefile is one word. Don't ask why...it just is.
	
	Makefiles are used to make compilation and linking easier for you, the programmer. 
	Typing:
	
	
gcc -g -o myprogram myprogram.s iofunc.o
	
	can get a little tedious. Now imagine if your program consisted of 2 files, now 10 files, now 100 files!
	Compiling would be unbearable! Lucky for us, there are makefiles!
	
 
	
	
	Makefile Basics
	
	A makefile is a simple file which is understood by a program called 'make' (and for the GNU
	lovers out there, there's gmake). A makefile is 
ALWAYS named "Makefile" (remember, Unix is
	case sensitive, so your makefile needs to start with a capital M).
	
	To create your first makefile, type the following:
	
		touch Makefile
		emacs Makefile
	
	
	If everything worked, that should have created for you an empty file called Makefile, and opened it
	up in emacs. Now we need to enter something into the body of the makefile. Makefiles can have variables
	contained within them. Common variables include:
	CC - The compiler to use
	CFLAGS - The compiler flags
	EXEC - The name of the executable to create
	
	So, let's make some variables. Type the following into the makefile (in the emacs window we just opened):
	
		CC=gcc
		CFLAGS=-g
		EXEC=asn3
		(Add a blank line in here)
	
	
	Okay, now we need to tell make what to do.
	
 
	
	
	Targets, Dependencies, and Commands
	
	Now that we have a few variables, we need to tell Make what to do when it runs our makefile. We'll need
	to make a Target. A target is what we're trying to build or compile. So for assignment 3, we might call it
	asn3.out. Following a target are the dependencies, these are the files that we need to build the target with.
	Make will go out and see if the dependencies are newer than the target, if they are, it will know to rebuild
	the target. A sample target line would look like this:
	
asn3.out: asn3.m iofunc.o stringio.s macrodefs.m
	
	There you can see the target is asn3.out (and notice the colon that separates the target from the dependencies).
	The dependencies are asn3.m, iofunc.o, stringio.s and macrodefs.m.
	
	Now we have to tell make how to rebuild that darned target. Make will simply execute the following lines (which 
	
MUST be indented with a tab) to build the file. So...what do we do? Add those lines.
	
		m4 asn3.m > asn3.s
		gcc -o asn3.out asn3.s iofunc.o stringio_libs.c
		(Don't forget to start each line with a tab!)
	
	
	Note: You need to replace the word 'TAB' with a real TAB character...made by pressing the TAB key.
	
	Notice that macrodefs.m is in the dependency list even though it doesn't appear in the commands. You'd want
	to recompile if you changed macrodefs.m, this is why it appears here.
	
 
	
	
	But Dan, we never used those variables we made!
	
	Oh yeah, good point. Okay, let's beef up our makefile a bit and use those variables. Change the line:
	
	
gcc -o asn3.out asn3.s iofunc.o stringio_libs.c
	to
	
$(CC) $(CFLAGS) -o $(EXEC) asn3.s iofunc.o stringio_libs.c
	
	Notice that when I reference the variables, I use $(variable name). This notation (dollar sign and brackets)
	simply tells make that I want it to use the appropriate variable there. We can also use the $(EXEC) variable in
	as the target name. (I'll leave that up to you to change.)
	
 
	
	
	Running Make and Common Targets
	
	To run your makefile, simply type "make" or "make target" at the shell prompt in the directory where
	your makefile is. If you don't specify a target, make will build the first target it finds. This first
	target should always be your executable, this way, everyone will know how to build your program!
	
	There are a few targets that are usually expected, they are:
	clean
	realclean
	and sometimes test...but we won't worry about that one today.
	
	Clean and realclean simply remove your intermediate files (for our class, that would be the .s file, since
	we rebuild it from the .m each time). 'realclean' generally removes temporary files (usually ending with ~) and
	.o files...but in our case, we don't want to remove the .o files because we need them to build our programs! 
	Don't worry about realclean. Let's make the clean target:
	
	
	
	(blank line between the last command line of the previous target and this new target)
	clean:
	    rm -f asn3.s
	    rm -f $(EXEC)
	
	 
	
	
	The final product
	
	If we did everything right, we should end up with a file that looks like this:
	
	# A sample makefile for CS208
	#
	# By Dan Santoni
	# 
	
	
	CC=gcc
	CFLAGS=-g
	EXEC=asn3.out
	
	$(EXEC): asn3.m iofunc.o stringio.s macrodefs.m
	    m4 asn3.m > asn3.s
	    $(CC) $(CFLAGS) -o $(EXEC) asn3.s iofunc.o stringio_libs.c
	
	clean:
	    rm -f asn3.s
	    rm -f $(EXEC)
	
	 
	
	
	Common Problems:
	
	If you get '*** missing separator' you probably used spaces instead of tabs.
	
	If you get '*** No rule to make target `foo', needed by `find'.  Stop.' then you have a dependency
	in your makefile that doesn't exist. Check for type-os and make sure all the dependency files are 
	in your assignment directory.
	
	
	By Dan Santoni
	with notes by Maia Hoeberechts