Assignment #7

Using the make utility

CS371 Spring 2000
Date Issued 02/29/'00
 Date Due 03/07/'00

Introduction

Make is a program which is used to maintain, update, and regenerate related programs and files.

Make provides a simple mechanism for maintaining the latest version of programs that result from many operations on a number of files. It is possible to tell Make the sequence of commands that create certain files, and the list of files that require other files to be current before the operations can be done. Whenever a change is made in any part of the program, the Make command will create the proper files with  minimum effort.

You can look up the online manual pages for more information.

In the simplest case, make is executed without explicit parameters:

        make

Makefile

Make is driven by an auxilliary file, called the MAKEFILE that defines which files make up a program. In addition, the makefile shows the relationship between the files, also called the DEPENDENCY. Make takes responsibility for recompiling any source files that has been changed since the last time it had been compiled and also for recompiling any source file that depends on other source files that have changed. This means you no longer have to remember which files have recently changed. You don't have to recompile everything, just in case.

make can also do other routine tasks often required in program administration. For example, make can be used to list and make backup copies for only those source files that had been changed since their last printing and backup.

When you run make with no arguments, it searches for a file named makefile, or if there is no file by that name then Makefile.

A makefile contains the following information:

1. Macro definitions at the beginning of the description file have the following form:

        name = string

e.g.    CFLAGS = -O

2. Information on file dependencies followed by executable commands
. A dependency line shows the relationship between a target file name given to the left of the colon, and the files that the target depends on, given to the right of the colon. The command line(s), also called RULES that follow the dependency line are assumed to transform the dependency files into the target file. The basic format for dependency rule is:

        target: [ dependency ...]

                [ command line ....]
 

As shown above, the commands are grouped below the dependency line and are typed on lines that begin with a tab. Subsequent lines that start with a tab symbol are taken as the commands lines that comprise the targets rule. A common error is to use space characters instead of the leading tab. Lines that start with a # are treated as comments. If make finds a makefile, it begins the dependency check with the first target entry in the file. You can also indicate the target explicitly as a parameter when calling make.
 

A simple example of a Makefile

        # Makefile for creating an executable file from two independently compiled

        # C source files

        CFLAGS= -O -g

        CC= gcc

        try: try.o functions.o

                $(CC) $(CFLAGS) -o try try.o functions.o

        try.o: try.c

                $(CC) $(CFLAGS) -c try.c

        functions.o: functions.c

                $(CC) $(CFLAGS) -c functions.c

        clean:

                rm try try.o functions.o
 

The first two lines define two macros, one for compilation flags and the other the CC (Compiling Command) macro.

When make is run on this makefile it sets its target to the first target in the Makefile - the file try.

The executable file try depends on try.o and functions.o .The command for creating the try is

        gcc -O -g -o try try.o functions.o

In order to complete the creation of the file try,  it will set subtargets try.o and functions.o, as described in the dependency rule.
The -o option places the output in file try.  This applies regardless  to  whatever sort of output gcc is producing, whether it be an executable file, an object file, an  assembler  file or preprocessed C code.
 The  -g  option  produces debugging information in the operating system's native  format . GDB can  work with this debugging information.
  With the option  `-O'  the compiler tries to reduce code  size  and execution time. Without `-O', the compiler's goal is to reduce the cost  of  compilation  and  to make debugging produce the expected results.

The try.o file depends on try.c and is created by the command

        gcc -O -g -c try.c

Similarly, functions.o depends on functions.c and is created by the command

        gcc -O -g -c functions.c

Another way to do the same is to run

        make try

indicating the main target explicitly.

The last two lines define a rule used to remove the executable and object files. It will work when this target is indicated explicitly:

        make clean

Because the target clean is not mentioned in other dependency rules it can be achieved only when called explicitly. Note that in both cases make uses (by default) the same Makefile.
 

Assignment (10 points)

Write a Makefile for compiling the C program qsort. The source code is stored in two files qsort.c(which contains  the main function) and functions.c (which contains the subroutines).

Your Makefile should meet the following requirements:

1. The executable file called qs.

2. Your Makefile should be able to cleanup the working directory (i.e. remove executable file qs and all object files when required.)

E-mail your makefile to the TA on the midnight of  the due date.
 
 

CS371 Home | HW List |