Using Makefiles

Why use make files?

It is important to follow the exact guidelines for creating make files.

Reduce Compile Command Length

Sometimes, you may find that the compile command for some programs can be very long and tedious to type over and over again. For instance, the compile line for graphics programs is rather long, and you might be tired of typing it; one way to avoid this is to create a "Makefile". A Makefile is a command file for compiling programs. For example, lets assume that we have a graphics program called face.cpp, and that the compile line is

    g++ -o face face.cpp -L/usr/X11R6/lib -lm -lX11 -lgd -lg2

We would create a file named "Makefile", and in it we should put the lines

    face: face.cpp
        g++ -o face face.cpp -L/usr/X11R6/lib -lm -lX11 -lgd -lg2

Now to compile face we would use the command



    make face

A Makefile can also be used to compile more than one program.

For example, we have face.cpp and pumpkin.cpp; here's a Makefile that can be used to compile both:

pumpkin: pumpkin.cpp
    g++ -o pumpkin pumpkin.cpp -L/usr/X11R6/lib -lm -lX11 -lgd -lg2
face: face.cpp
    g++ -o face face.cpp -L/usr/X11R6/lib -lm -lX11 -lgd -lg2

To compile pumpkin, we would type

    make pumpkin

To compile face, we would type

    make face

As you create more programs, you may add them to the Makefile if you so desire.

Guidelines for making Makefiles

  1. The Makefile must be spelled and capitalized exactly like we have it here: Makefile
  2. Your program name must be followed by a colon and then the filename as in: pumpkin: pumpkin.cpp
  3. After this line, there must be a tab and then whatever compile line you want.
  4. If you just type "make" at a prompt, it will compile the first program listed in the Makefile. In this case, typing "make" would compile pumpkin.

Project Management

Suppose you are working on a project that contains multiple C++ classes, you should code and test the classes separately. Breaking the project into multiple files helps you do this.

For each class create a header file and a source file. The header file contains the class definition, prototypes of the member functions, type definitions, constants, and global variables used by the class; all programs that use this class will include this header file. The source file contains the actual source for the member functions.

For example, let's assume that our project requires a simple calculator class with Add and Multiply functions. Here's one possible header file (calculator.h):

class Calculator
float temp_var;
float calculator_Add ( float a, float b );
float calculator_Multiply ( float a, float b );

The actual source might look something like this (calculator.cpp):

#include "calculator.h"
float Calculator::calculator_Add ( float a, float b )
temp_var = a + b;
return( temp_var );
float Calculator::calculator_Multiply ( float a, float b )
temp_var = a * b;
return( temp_var );

The following program would be a good test program (mycalctester.cpp):

#include <iostream.h>
#include "calculator.h"

void main (void)
float x, y;
float result;

Calculator mycalc;

x = 10;
y = 10;

cout << " x = " << x << endl;
cout << " y = " << y << endl;
cout << endl;

result = mycalc.calculator_Add (x, y);
cout << " x + y = " << result << endl;

result = mycalc.calculator_Multiply (x, y);
cout << " x * y = " << result << endl;


Start by compiling calculator.cpp into a object file. Assuming that you are using a UNIX system, you do this with the command:

    g++ -c calculator.cpp

This creates a file called calculator.o

To compile the test program mycalctester.cpp, you would use the command:

    g++ -Wall -o mycalctester mycalctester.cpp calculator.o

Unfortunately, if you change the calculator.cpp, you must issue both compile commands. To simplify project management, you may want use makefiles. A makefile is a simple tool to update your project without having to recompile all the source files again. With "make" you will only compile the code fragments that have been modified and the fragments that depend on them. For instance, mycalctester.cpp depends on calculator.cpp; if mycaltester.cpp is modified, then you need to recompile everything. If you modify mycalctester.cpp and nothing else, then you only need to compile mycalctester.cpp.

Here is an example makefile for the programs listed above (Makefile):

mycalctester: mycalctester.cpp calculator.o calculator.h
g++ -o mycalctester mycalctester.cpp calculator.o
calculator.o: calculator.cpp calculator.h
g++ -c calculator.cpp

To execute the makefile use the command



    make mycalctester