Operating Systems - Projects and Exercises

The make Utility

The left arrow above will return you to the Home page
The left arrows below will return you to the Previous page

Go back top

Large projects usually require multiple program files - i.e. the C source code is split between several source code files - why?

  1. Large projects can involve many programmers - it’s better you each work on your own program file.
  2. Very large source code files are hard to navigate and understand.
  3. Grouping code associated with the same basic task (e,g, data input) into the same file aids modularity and understandability
  4. Separate files = separate compilation = faster compilation

Using a makefile

Format of a makefile:

e.g. Consider an executable program called main with source files utils.c screen.c main.c. All function headers and #defines shared between files would be in main.h.

The makefile will look like this:-

main: main.o utils.o screen.o
    gcc main.o utils.o screen.o -o main
main.o: main.c main.h
    gcc -Wall -c  main.c
utils.o: utils.c main.h
    gcc -Wall -c utils.c
screen.o: screen.c main.h
    gcc -Wall -c screen.c

Terminology:-

 

main: main.o utils.o screen.o


dependency line must
start in column 1

     

gcc main.o utils.o screen.o -o main


action line must start with a tab

Dependency + Action = Rule

make reads a makefile sequentially.

Each action line defines what needs to be done to create the object in the dependency line - dependency line shows what object depends on.

make uses rules to build the dependency tree:

main

main.o

utils.o

screen.o

main.c

main.h

utils.c

main.h

screen.c

main.h

To make a program file, first type make at the command line. The make utility reads the first rule - if all the .o files are unchanged since last compilation (time comparison) then no action is taken - if one .o file has changed then the rule associated with that file is fired. If no .o file exists then it is created.

make has several features to make things easier: -

a built-in rule is that a .o file depends on corresponding .c file, therefore .c files do not need to be included in a dependency line.

So for example the utils.o rule:

utils.o: utils.c main.h
    gcc -Wall -c utils.c

can be replaced with:

utils.o: main.h
    gcc -Wall -c utils.c

Also we have a macro $*.c to represent a series of .c related to object files: -

main.o utils.o screen.o: main.h
    gcc -Wall -c $*.c

This rule means if main.h is changed then all the related .c files must be recompiled and replaces most of the previous makefile:

main.o: main.c main.h
    gcc -Wall -c  main.c
utils.o: utils.c main.h
    gcc -Wall -c utils.c
screen.o: screen.c main.h
    gcc -Wall -c screen.c

However, if an individual .c file is changed, the related .o file is remade automatically because of another built-in rule. This means the $*.c macro can be omitted entirely and the original makefile can be written as:

main: main.o utils.o screen.o
    gcc main.o utils.o screen.o -o main
main.o utils.o screen.o: main.h

However, this will use the default compiler and flags for the compiler and you may need to override the defaults using the following macros:

CC = gcc
CFLAGS = -Wall

In addition makefile will accept macros to replace long strings of files, for instance:

OBJECTS = main.o utils.o screen.o

This can be referred to as $(OBJECTS) (note that macros appear at top of makefile). Hence makefile can again be rewritten as :

CC = gcc
CFLAGS = -Wall
OBJECTS = main.o utils.o screen.o
main: $(OBJECTS)
        $(CC) $(OBJECTS) -o main
$(OBJECTS): main.h
  

Comments

All lines beginning with a # are ignored and can be used to add comments to the makefile:

# Joe Citizen, s1234567 - Operating Systems Project 1
# CompLab1/01 tutor: Fred Bloggs
 
CC = gcc
CFLAGS = -Wall
PROGNAME = myshell
OBJECTS = myshell.o utility.o
INCLUDES = myshell.h
 
$(PROGNAME): $(OBJECTS)
       $(CC) $(OBJECTS) -o $(PROGNAME)
$(OBJECTS): $(INCLUDES)

This can obviously be used as a very general template.

Go back top

For use only by students and instructors using the supplementary material available with the text book: "Operating Systems - Internals and Design Principles", William Stallings, Prentice Hall, 5th Edition, 2004. Not to be printed out or copied by any other persons or used for any other purpose without written permission of the author(s).

©