Makefiles

UNIX has a program called "make" that solves two persistent, annoying problems with developing programs that consist of several parts:

  1. What is the sometimes-complex set of commands I have to issue to (re)compile my object files and executable; and
  2. Which object files do I need to recompile because I've changed the source, and which files then depend upon those rebuilt files, and so forth.

We'll be going into the incredible power of full-blown "make" later; for now, we will learn how to get it to do simple builds, which still saves time and effort, and avoids mistakes.

"make" depends on the programmer to provide a description of how the proram is put together. This description is provided by the programmer in a text file called a "makefile". This file is typically named "Makefile" with a capital 'M' to make it appear at the top of the file listings, and the "make" program looks for this file as one of the defaults.

A Makefile consists of multiple sections, called "rules", that specify how the program is built. Each rule consists of a header line, listing the target file and the files the target depends upon (the "prerequisites"), followed by zero or more lines specifying the commands that would be used to actually construct the target file (the "build actions" or "recipe". "make" compares the last-modified timestamp of the target file with those of the prerequisites it depends on, and if any of the prerequisites is newer, make will trigger the recipe to bring the target up-to-date.

Without further ado, here's a very simple Makefile:

program.out: program.cpp
	g++ -Wall program.cpp -o program.out

And that's it! Assume you wrote your first C++ program into a source file called "program.cpp". If you also had the above Makefile, you would just type "make" to the shell. The "make" program would look for a file called "Makefile", find it and process it, and see your one rule. It would know that the desired target was the file "program.out". It would compare the modified time of program.out to program.cpp. If program.out didn't exist (as it wouldn't the first time we did "make"), or if you had edited program.cpp since the last time you compiled, "make" would detect this and decide to rebuild, so it would execute "g++ ...", rebuilding the executable "program.out". If you were to immediately run "make" again, it would notice that program.out was up-to-date (i.e., exists and is newer than the source program.cpp), and do nothing.

Now, for this lab, modify the sample Makefile given above to work for the program you wrote in the previous part of this lab.