Tutorial on Makefiles A quick introduction to makefiles. Make is a standard UNIX utility for maintaining a collection of files where some depend on others. It is most commonly, but not exclusively, used to maintain software-related files. A file describes the relationships among a collection of files; that file is often called "Makefile" or "makefile", but can have any name, if make is invoked with the "-f" option: make -f "mymake" The primary component of a makefile is a sequence of rules. A rule has three parts, a target, a list of dependences, and a list of commands. For example, in this rule foo: foo.cc foo.h bar.h g++ -o foo foo.cc the single target, appearing before the colon, is foo (an executable file). The dependences are the files foo.cc, foo.h and bar.h. It is reasonable to assume that foo.cc includes foo.h and bar.h, so that if either changes, foo.cc is also changed indirectly. Finally, lines following the target/dependences pair each begin with a tab character and contain commands, to be executed in order, that describe how to use the dependeces to make the target. This rule is applied when we type "make foo", or when we type "make" and foo the target of the first rule in the file. Finally, the rule is applied if we must update foo in order to complete the construction of some other target. Make goes through the following steps when examining this rule. Is there a file "foo" that is no older than the files it depends on? If so, continue without considering this target any longer. Otherwise, is there another rule with foo.cc as target? Then make foo.cc. is there another rule with foo.h as target? Then make foo.h. is there another rule with bar.h as target? Then make bar.h. then carry out the commands to build foo. A typical makefile for a simple program might look like mainprog: mainprog.o foo.o bar.o g++ -o mainprog mainprog.o foo.o bar.o mainprog.o: mainprog.cc foo.h bar.h g++ -c mainprog.ccc foo.o: foo.cc foo.h bar.h g++ -c foo.cc bar.o: bar.cc bar.h g++ -c bar.cc Here, typing "make" to build "main" in a directory that contains only source code will first seek to build the dependences of main (the *.o files), and only when they are done, put the pieces together to make the executable program. Typing "make bar.o", on the other hand, would do no more than make that one file. The dates on files are examined, so that nothing is re-made that doesn't need to be. One advantage of using many small program files, instead of one large one, is that the time to recompile and relink an executable program is greatly reduced if only one small file has to be compiled. Some aspects of make rules are so frequent, that abbreviations are available. For example, since we are always using the same C++ compiler, we could set the makefile variable CXX=g++ and replace g++ everywhere with $(CXX) to get essentially the same makefile, but one where changing just one line lets us to use a new compiler in every statement. The notation $(var) is just make's peculiar way of getting the value out of a variable. Another common variable is CXXFLAGS CXXFLAGS = -g bar.o: bar.cc bar.h $(CXX) $(CXXFLAGS) -c bar.cc where now, with the change of a single variable (assuming you use $(CXXFLAGS) everywhere), you can change the optimization level or debugging level the compiler uses to compile your program. So, with these two enhancements, we might have CXX = g++ CXX_FLAGS = -g main: mainprog.o foo.o bar.o $(CXX) -o main mainprog.o foo.o bar.o mainprog.o: mainprog.cc foo.h bar.h $(CXX) $(CXXFLAGS) -c mainprog.cc foo.o: foo.cc foo.h bar.h $(CXX) $(CXXFLAGS) -c foo.cc bar.o: bar.cc bar.h $(CXX) $(CXXFLAGS) -c bar.cc which will tell make to compile the pieces of your program with extra debugging information included. There are default rules for the sitution that describes the commands to use when no commands are specfied, to build a file that ends with one suffix from files that begin with another. For example, there is a default rule that says that to build .o file form a .cc file, you do this: $(CXX) $(CXXFLAGS) -c which is what we're doing anyway. So we could reduce our last 3 rules to merely mainprog.o: mainprog.cc foo.h bar.h foo.o: foo.cc foo.h bar.h bar.o: bar.cc bar.h and the right things would happen. There's lots more tricky things one can do with make, but these basics should be enough for you for a while.