Nothing Special   »   [go: up one dir, main page]

Makefile

Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

Makefile

Objectives

z Header Files.

z Compilers and Linkers.

z Using Makefile to Build Large Applications.

1. Header files(or include files)


Why we need header files? A large program can be broken up into smaller compoennts such
as subroutines. And those components can be distributed among source files, which are compiled
separately. Once a subroutine needs to be used somewhere other than where it’s defined. The
function prototypes must be introduced. The function prototypes can be writen in a header file.
How to include header files in a source code?
#include<filename> for c standard header files, eg. #include<stdio.h>
#include”filename” for file in the current directory.
Example 1. Including a header file

//fact.h
#include<stdio.h>
int factorial(int);

//fact.c //main.c
#include "fact.h" #include "fact.h"

int factorial(int n) int main()


{ {
int i, k; int n;
if(n == 0) n = 8;
return 1; printf("%d!=%d\n",n,factorial(n));
k = 1; }
for(i=1; i<=n; i++)
k *= i;
return k;
}

1
In the above example, we write two lines in the header fact.h
#include<stdio.h> //include the a standard c header file stdio.h
int factorial(int) //gives the prototype of a subroutine factorial.

When we use #include "fact.h", main.c knows “factorial “ is a subroutine which has an
integer as its argument and returns an integer.

2. Compilers and Linkers


In our previous classes, we use
gcc –o ex1 ex1.c
to convert the source code ex1.c into an executable ex1. gcc converts the source code ex1.c into
ex1 by several steps, The most important two steps are
Compiling: gcc generates object code or an object file by processing a source code file ex1.c.
Linking: gcc generates an executable ex1 by linking object files together. (for example, if we use
printf or scanf in ex1.c, gcc will link a standard library containing printf and scanf)

For small applications, we can use a one line command like


gcc –o ex1 ex1.c
to generate the executalbe. However, for a large application which contain several source files,
this simple method does not work. We ususlly do compiling and linking separately for large
applications.

Example 2. Generating object files and executables separately


We will generate an executable main from example 1 with the following steps
gcc –c factorial.c
gcc –c main.c
gcc –o main factorial.o main.o

The first and second line will generate two object files factorial.o and main.o.
The last line will link them to generate an executable main.

3. Using Makefile to Build Large Applications

http://www.gnu.org/software/make/manual/make.html

3.1 Basics for Make


In example 2, we have to type 3 lines to get the executable. We need a tool to generate
executables automatically. Make is a utility for automatically building large applications. The
following is an example of makefile

2
Example 3. The Example Makefile
makefile
#comment: 1. makefile example

main: fact.o main.o


gcc -o main fact.o main.o

fact.o: fact.c fact.h


gcc -c fact.c

main.o: main.c fact.h


gcc -c main.c

clean:
rm -rf *.o main

Using Make to generate executable: make (using makefile as the default input) or
make –f filename (using filename as the input)

A target A dependency line(prerequisite)

main: fact.o main.o


gcc -o main fact.o main.o
A rule

A shell line

A rule: One makefile is composed of several rules, it tells Make when and how to make a file.
A dependency line(prerequisite): it tells Make which files the target depends on.
A shell line: it tells Make how to build a target.

3
fact.c fact.h main.c

fact.o main.o

main

Fig 1. The dependency from the example 3

For example
main: fact.o main.o
tells us main depends on two files fact.o and main.o, if fact.o or main.o is newer than main or
main does not exist. Make will run the shell line
gcc -o main fact.o main.o
to generate the executable main.

The Make Process is Recursive! For example, if we change main.c and type make, we will see
the following line is executed(Note the above graph)

gcc -c main.c
gcc -o main fact.o main.o

question: 1. If you change fact.h and type make, what will happen?
2. Type “make clean”, what will happen?

Additional dependencies: From the above graph, we see both fact.c and main.c depend on fact.h,
we can use a new line to list this relation:

Example 4. Additional dependencies

4
mk1
main: fact.o main.o
gcc -o main fact.o main.o

fact.o: fact.c
gcc -c fact.c

main.o: main.c
gcc -c main.c

fact.o main.o: fact.h

clean:
rm -rf *.o main

3.2 Defining Variables


Example 5. Variables
mk2
#comment: use variables and predefined variables
OBJS = fact.o main.o
CC = gcc
LD = gcc

main: $(OBJS)
$(LD) -o main $(OBJS)

fact.o:fact.c
$(CC) -c fact.c
main.o: main.c
$(CC) -c main.c

$(OBJS) : fact.h

clean:
rm -rf *.o main

There are some predefined variables in GNU make, see


http://www.gnu.org/software/make/manual/make.html#Implicit-Variables some commonly used
variables are
CC Program for compiling C programs; default `cc'
FC Program for compiling or preprocessing Fortran and Ratfor programs;
default `f77'.
CXX Program for compiling C++ programs; default `g++'.

5
We can print out the values for the predefined variables by using

#print the values for variables


echo:
echo $(CC)
echo $(FC)
echo $(CXX)

3.3 Pattern Rules


In large applications, we may have a lot of source files to deal with. We may need to write a
lot of rules. One way to simplify the makefile is to use pattern rules. See the following
http://www.gnu.org/software/make/manual/make.html#Pattern-Rules

We only talk about static pattern rule here,


http://www.gnu.org/software/make/manual/make.html#Static-Pattern

Here is the syntax of a static pattern rule:


targets ...: target-pattern: prereq-patterns ...
commands
...
The targets list specifies the targets that the rule applies to. The target-pattern and prereq-patterns
say how to compute the prerequisites of each target. Each target is matched against the
target-pattern to extract a part of the target name, called the stem. This stem is substituted into
each of the prereq-patterns to make the prerequisite names (one from each prereq-pattern).

Example 6 Using static pattern rules


With the help of pattern rules, we can rewrite examples 3 in a simpler format.
mk3
OBJS = fact.o main.o
CC = gcc
LD = gcc
main: $(OBJS)
$(LD) -o main $(OBJS)

$(OBJS) : %.o : %.c


$(CC) -c $< -o $@

$(OBJS) : fact.h
clean:
rm -rf *.o main

How it works:

6
See http://www.gnu.org/software/make/manual/make.html#Automatic-Variables for the means of
$<, $@.

Here the targets $(OBJS) = fact.o main.o


The target-pattern %.o first matches fact.o and so % = fact, then prereq-pattern = fact.c, we get
the first rule
fact.o: fact.c
$(CC) –c fact.c -o fact.o
Then the target-pattern %.o matches main.o, we got the second rule
main.o: main.c
$(CC) –c main.c -o main.o

Therefore,
$(OBJS) : %.o : %.c
$(CC) -c $< -o $@
is equavilent to two rules
fact.o: fact.c
$(CC) –c fact.c -o fact.o
main.o: main.c
$(CC) –c main.c -o main.o

You might also like