0% found this document useful (0 votes)
33 views17 pages

Unix Makefiles

The document describes how makefiles in Unix work. Makefiles contain rules and dependencies that tell the make utility how to compile a program. The make utility will only recompile files that have changed or depend on changed files, making the build process more efficient. It provides examples of components in a makefile like rules, dependencies, shell lines, and macros.

Uploaded by

Kevin Smith
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views17 pages

Unix Makefiles

The document describes how makefiles in Unix work. Makefiles contain rules and dependencies that tell the make utility how to compile a program. The make utility will only recompile files that have changed or depend on changed files, making the build process more efficient. It provides examples of components in a makefile like rules, dependencies, shell lines, and macros.

Uploaded by

Kevin Smith
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
You are on page 1/ 17

Unix Makefiles

COP 3330
Lecture Notes
Dr. David A. Gaitros

Introduction
The make utility in Unix is one of the original tools designed
by S. I. Fieldman of AT&T Bell labs circa 1977. There are many
version.
What is make?: The tool is designed to allow programmers
to efficiently compile large complex programs with many
components easily.
You can place the commands to compile a program in a Unix
script but this will cause ALL modules to be compiled every
time.
The make utility allows us to only compile those that have
changed and the modules that depend upon them.

How Does it Work?


In Unix, when you type the command make the operating
system looks for a file called either makefile or Makefile.
There are exceptions to this but we will assume that you will always
have the makefile or Makefile file resident in the directory of
where your program resides.

This file contains a series of directives that tell the make


utility how to compile your program and in what order.
Each file will be associated with a list of other files by which it
is dependent. This is called a dependency line.
If any of the associated files have been recently modified, the
make utility will execute a directive command just below the
dependency line.

How Does it Work?


The make utility is recursive. For instance, if
a very low level utility is the only thing
changed, it could cause all of the modules
within a program to be re-compiled.
After the utility finishes the file, it goes
through and checks all of the dependencies
again to make sure all are up to date.

Simple Example
hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello
main.o: main.cpp
g++ -c main.cpp factorial.o: factorial.cpp
g++ -c factorial.cpp
hello.o: hello.cpp
g++ -c hello.cpp
clean:
rm -rf *o hello

The Tree
hello

main.o

factorial.o

factorial.o

hello.o

factorial.cpp
hello.cpp

main.cpp
clean

Components of a Makefile

Comments
Rules
Dependency Lines
Shell Lines
Macros
Inference Rules

Comments
A comment is indicated by the character #. All text that
appears after it will be ignored by the make utility until the
end of line is detected.
Comments can start anywhere. There are more complex
comment styles that involve continuation characters but
please start each new comment line with an # and avoid the
more advanced features for now.
Example
#
# This is a comment
projecte.exe : main.obj io.obj

# this is also a comment.

Rules
Rules tell make when and how to make a file. The format is as
follows:
A rule must have a dependency line and may have an action or shell
line after it. The action line is executed if the dependency line is out of
date.
Example:
hello.o: hello.cpp

g++ -c hello.cpp

This shows hello.o as a module that requires hello.cpp as source


code. If the last modified date of hello.cpp is newer than hello.o, than
the next line (shell line) is executed.
Together, these two lines form a rule.

Dependency Lines

The lines with a : are called dependency lines.

To the left are the dependencies


To the right are the sources needed to make the dependency.

At the running of the make utility, the time and date when Project.exe was last
built are compared to the dates when main.obj and io.obj were built. If either
main.obj or io.obj have new dates, then the shell line after the dependency line is
executed.
The make process is recursive in that it will check all dependencies to make sure
they are not out of date before completing the build process.
It is important that all dependencies be placed in a descending order in the file.
Some files may have the same dependencies. For instance, suppose that two files
needed a file called bitvect.h. What would the dependency look like:
main.obj this.obj: bitvect.h

Shell Lines
The indented lines (must have tab) that follow each
dependency line are called shell lines. Shell lines tell
make how to build the target.
A target can have more than one shell line. Each line
must be preceded by a tab.
After each shell is executed, make checks to see if it
was completed without error.
You can ignore this but I would not at this point.

Shell Lines
After each shell line is executed, Make checks the shell line
exit status.
Shell lines that returning an exit status of zero (0) means
without error and non-zero if there is an error.
The first shell line that returns an exit status of non-zero will
cause the make utility to stop and display an error.

You can override this by placing a - in front of the


shell command, but I would not do this.
Example:
- gcc o my my.o mylib.o

Macros
Comes from the Greek word makros meaning large.
Basically it is a shorthand or alias used in the
makefile
A string is associated with another usually larger
string
Inside the file, to expand a macro, you have to place
the string inside of $( ) .
The whole thing is expanded during execution of the
make utility.

Macros
Examples of macros:
HOME = /home/courses/cop4530/spring02
CPP = $(HOME)/cpp
TCPP = $(HOME)/tcpp
PROJ = .
INCL = -I $(PROJ) I$(CPP) I$(TCPP)
You can also define macros at the command line such as
Make DIR = /home/faculty/whalley/public_html/cop5622proj/lib2
And this would take precedence over the one in the file.

Inference Rules
Inference rules are a method of generalizing the
build process. In essence, it is a sort of wild card
notation.
The % is used to indicate a wild card.
Examples:
%.obj : %.c

$(CC) $(FLAGS) c $(.SOURCE)


All .obj files have dependencies of all %.c files of the
same name.

Example of an average size


makefile
CC = gcc
DIR = /home/faculty/whalley/public_html/cop5622proj/lib
CFLAGS = -g -I$(DIR) -I. -c
LFLAGS = -g
opt: analysis.o flow.o io.o misc.o opt.o opts.o peephole.o regs.o vect.o
$(CC) $(LFLAGS) -o opt analysis.o flow.o io.o misc.o opt.o opts.o peephole.o regs.o vect.o
analysis.o: analysis.c analysis.h $(DIR)/misc.h $(DIR)/opt.h $(DIR)/vect.h
$(CC) $(CFLAGS) analysis.c
flow.o: $(DIR)/flow.c $(DIR)/flow.h $(DIR)/opt.h
$(CC) $(CFLAGS) $(DIR)/flow.c
io.o: $(DIR)/io.c $(DIR)/io.h analysis.h $(DIR)/misc.h $(DIR)/opt.h peephole.h $(DIR)/regs.h
$(CC) $(CFLAGS) $(DIR)/io.c

misc.o: $(DIR)/misc.c $(DIR)/misc.h $(DIR)/opt.h


$(CC) $(CFLAGS) $(DIR)/misc.c
opt.o: $(DIR)/opt.c $(DIR)/opt.h
$(CC) $(CFLAGS) $(DIR)/opt.c
opts.o: opts.c $(DIR)/misc.h $(DIR)/regs.h $(DIR)/opt.h opts.h
$(CC) $(CFLAGS) opts.c
peephole.o: peephole.c $(DIR)/misc.h $(DIR)/regs.h $(DIR)/opt.h peephole.h
$(CC) $(CFLAGS) peephole.c
regs.o: $(DIR)/regs.c $(DIR)/regs.h $(DIR)/opt.h
$(CC) $(CFLAGS) $(DIR)/regs.c
vect.o: $(DIR)/vect.c $(DIR)/vect.h $(DIR)/opt.h
$(CC) $(CFLAGS) $(DIR)/vect.c

You might also like