[WPI] [cs2223] [cs2223 text] [News] [Notes] 

cs2223, D97/98: make, a Program Managament Utility

Introduction

As programs grow in complexity, management of the program becomes increasingly difficult. Often large programs span several source and header files. Changing any one of them requires recompilation and linking some portion of the program modules. It is easy to forget which other parts of the program are affected when an individual module is changed. This is particularly a problem when several people are working on the same program.

The utiliy make helps to manage the software development process. Basically what it does is to keep track of which modules have been modified and when. By comparing modification dates and a dependency list, make determines which modules need to be recompiled and relinked when rebuilding your program after any module is changed. Let's look at an example.

Suppose your program consists of five source files plus two header files, each of which is used in some, but not all, of the source code files. If you change one of the header files, some of the source code files need to be recompiled and the resulting object code files need to be relinked to produce a new executable version of your program. Instead of looking inside each source file to decide which to recompile, and issuing a set of g++ commands with different source and object file names, a single command is used -- something like this:

make my_prog

The utility make will look for a file called "makefile" or "Makefile" (no quotes, no extension) which contains a dependency list and compilation instructions. Most systems require that all but the first letter be lowercase; some systems will only take one version of this name, so you may have to experiment. The list looks very similar to the string of g++ commands you would normally type, except they are all contained in a single file.

A typical make file looks like this:

my_prog : main.C file1.o file2.o file3.o file4.o head1.h
	g++ -o my_prog main.C file1.o file2.o file3.o file4.o
 
file1.o : file1.C #this is how to include a comment
	g++ -o file1.o file1.C -lm

file2.o : file2.C head1.h #this is a dependency line
	g++ -o file2.o file2.C #this is a command line 

file3.o: file3.C file1.h file2.h
	g++ -o file3.o file3.C


There are two types of lines in a makefile: depedency lines and command lines.

Each dependency line contains the name of an object module and its dependencies. The first line in the above makefile says that the object module my_prog depends on four object files and one header file. If any of those five files is changed, it is necessary to recompile my_prog. Note the use of the colon to separate the object name my_prog from the list of files on which it depends.

Each commaand line tells what to do to properly rebuild a object module if something changes. The second line in the above makefile says that the way to rebuild the object module my_prog is to use the g++ command to compile main.C, link it with four object files, and create an oject module called my_prog. These command lines are identical to the ones you would issue directly to the UNIX shell, one at at time. You can't see it above, but each command line begins with a tab character, not with spaces. Using spaces instead of a tab is a common error when writing makefiles. Notice how one of the command lines above tells g++ to include the math library.

Syntax of make files

Invoking make

You run make by typing make followed by the name of the target or object module. For example, if you type

make file2.o

the make utility checks to see whether file2.C or head1.h has been changed since the list time that file2.o was created. If either or both have changed, then the commnd

g++ -o file1.o file1.C -lm

is used to create a new version of file2.o. If neither file2.C nor head1.h has changed, then make quits without doing anything. Similarly, you can make any of the other targets in the makefile -- anything to the left of a colon on a dependencies line. If you type the command

make my_prog

then each of the dependency list objects will be checked too. If, for example, head1.h has been changed than the files file2.o and file3.o will be regenerated (using their respective command lines from the makefile) before my_prog is regenerated using its own command line.

Remember, you must be in the same directory as the makefile and it has to be named exactly makefile for this to work.

Conclusions

If you use the make facility, it is easier to keep track of large programs. For example, as you work on individual files that are part of a large program, you need only change the files and, if necessary, change the makefile. Then instead of invoking g++ directly whenever you change anything, you use the make command to rebuild what you need when you need it and all dependencies are automataically accounted for.

This is only a brief introduction to a few of make's features. You can learn more by using the command

man make

on your workstation. Also, the books mentioned in the Notes page contain useful information.

--------------------
[WPI Home Page] [cs2223 home page]  [cs2223 text] [News] [Notes] 

Contents ©1994-1998, Norman Wittels
Updated 14Mar98