Compilation & linkage.h read.h.c read.c.c main.c.c list.c.h list.h prog1 Linkage: g++ read.o main.o...

Post on 15-Jan-2016

230 views 0 download

Tags:

Transcript of Compilation & linkage.h read.h.c read.c.c main.c.c list.c.h list.h prog1 Linkage: g++ read.o main.o...

Compilation & linkage

.h

read.h

.c

read.c

.c

main.c

.c

list.c

.h

list.h

prog1Linkage:

g++ read.o main.o list.o –o prog1

.o

main.o

.o

list.o

.o

read.o

Compilation:

g++ -c read.c main.c list.c

Compilation & linkage

.h

read.h

.c

read.c

.c

main.c

.c

list.c

.h

list.h

prog1

.o

main.o

.o

list.o

.o

read.o

If only one file is modified, do we have to recompile all over again?

No.

The Makefile uses the dependencies graph

Compilation & linkage

.h

read.h

.c

read.c

.c

main.c

.c

list.c

.h

list.h

prog1

.o

main.o

.o

list.o

.o

read.o

If read.h is modified, what should be done?

We have to recreate only a subset of the files!

Make

Make is a program who’s main aim is to update other programs in a “smart” way.

“smart” = Build only out-of-date files (use timestamps). Use the dependency graph for this.

You tell make what to do by writing a “makefile”

What makefile contains

Explicit rules Implicit rules Variable definitions Directives Comments

Explicit rules

Rule Syntax:

targets : prerequisites <tab> command <tab> ...

Targets: Usually files

Prerequisites: Other files that the targets depend on

Command: What to execute (shell command)

<tab> tells make it’s a command

Example

.h

read.h

.c

read.c

.c

main.c

.c

list.c

.h

list.h

prog1

.o

main.o

.o

list.o

.o

read.o

Makefile example:

prog1: read.o main.o list.og++ main.o read.o list.o –o prog1

main.o: main.c read.h list.hg++ -c main.c

read.o: read.c read.hg++ -c read.c

list.o: list.c list.hg++ -c list.c

makefile names

make looks automatically for : makefile, Makefile Override by using –f :

make –f MyMakefile

How Make works?

Make works as follows: Given a target:

Find the rule for it Check if the rule prerequisites are up to date

By “recursive” application on each of them If one of the prerequisites is newer than target,

run the command in rule body.

Example

Makefile:prog1: read.o main.o list.o

g++ main.o read.o list.o –o prog1

main.o: main.c read.h list.hg++ -c main.c

read.o: read.c read.hg++ -c read.c

list.o: list.c list.hg++ -c list.c

Running make:make prog1

read.h modified

Check prog1 Check read.o

Do: g++ -o read.c Check: main.o

Do: g++ -o main.c Target: list.o

Do: <nothing> Do:

g++ main.o read.o list.o –o prog1

Comments

# comments are easy

Variables

Make maintains variables Case sensitive Traditionally – use capital letters

FOO = 1

CFLAGS = -g

TARGETS = list.o main.o read.o

Rules can use variablesmain.o: main.c read.h list.h

g++ $(CFLAGS) –c main.c

Automatic VariablesSet automatically by Make, depend on current rule $@ - target $^ - list of all the prerequisites

including the directories they were found

$< - first prerequisite in the prerequisite list. $< is often used when you want just the .c file in the

command, while the prerequisites list contains many .h too

$? - all the prerequisites that are newer than the target

Many Others …….

Setting Variables

Using “=“ will expend variables recursively:

CFLAGS = $(include_dirs) –O

include_dirs = -Ifoo -Ibar This means you cant do:

CFLAGS = $(CFLAGS) -O #error !• You can append to it instead:

CFLAGS += -O

You can override variables when you run make:

make CFLAGS='-g -O''

Using Wildcards

Automatic Wildcard (*,?) expansion in: Targets Prerequisites Commands

clean:

rm -f *.o # good

objects = *.o # no good

# instead use wildcard function

# of make

objects := $(wildcard *.o) # good

Implicit rules

We saw “explicit rules” so far, e.g:list.o: list.c list.h

g++ -c list.c

Implicit rules (many kinds): Example, creation by suffices.

Create “.o” files from “.c” files

.c.o: $*.cg++ -c –o $@ $<

$* - the match without the suffix (e.g. list)$@ - file for which the match was made (e.g. list.o)$< - the matched dependency (e.g. list.c)

Implicit Rules

Now we can write:.c.o: $*.c g++ -c –o $@ $<

prog1: read.o main.o list.og++ main.o read.o list.o –o prog1

main.o: read.h list.h

read.o: read.h

list.o: list.h

The dependencies of main.o on main.c are specified in the rule

The command is also specified by the rule

Where make finds Prerequisites?

Default: current directory Better design:

separate object & binaries from source code Use variable VPATH to look for prerequisites.

You can set it in the makefile start to several directories:

VPATH = src:../headers #separate by “:” There is also vpath (lower case!) which make uses

for paths for specific file types. Read Manual.

Auto variables & Directory Search Commands are executed by the shell. You must be carefull

the shell will find what make found. Use $^ for this

VPATH = src:../headers foo.o : foo.c defs.h hack.h

cc -c $(CFLAGS) $< -o $@

Note that foo.c might be actually src/foo.c $@ expands to full pathname

This version will not work:

foo.o : foo.c defs.h hack.h cc -c $(CFLAGS) foo.c -o $@

Built In Implicit Rule

Make has a set of default implicit rules for compiling C C++ Fortran …

Built-in implicit rules make liberal use of certain predefined variables

command used to compile a C source file actually says `$(CC) -c $(CFLAGS) $(CPPFLAGS)'

Variables Controling Built-in Commands

Name of programs

CC - Program for compiling C programs CXX Program for compiling C++ programs

Arguments for programs:

• CFLAGS Extra flags to give to the C compiler. CPPFLAGS Extra flags to give to the C

preprocessor and programs that use it (the C and Fortran compilers).

CXXFLAGS Extra flags to give to the C++ compiler. • LDFLAGS Extra flags to give to compilers when

they are supposed to invoke the linker, `ld'.

Implicit Rules Revisted

Suffix Rules (old !):.c.o:

$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< Suffix rules cannot have any prerequisites of their

own:.c.o: foo.h # won’t work as you expect!!!

$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< Suffix rules use .SUFFIXES from suffix. You can

add to it by doing:

.SUFFIXES: .hack .win

Implicit Rules Revisted

You might prefer to work with a Pattern rule:%.o: %.c foo.h

$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $< Here you can also use empty commands, as it uses

the defaults ones. Control the default by changing the variables%.o: %.c foo.h # this is the same as above !

Phony Targets

clean:

rm *.o temp Target not really the name of a file. No file will be

created. What happens when there is a “clean” file in our

path? .PHONY is a built in target name. Its list of

prerequisites tells make which targets should not be treated as files.

Phony clean

This will work even “clean” file actually exist:.PHONY: clean clean:

rm *.o temp When one phony target is a prerequisite of another,

it serves as a subroutine of the other .PHONY: cleanall cleanobj cleanall : cleanobj cleandiff

rm program cleanobj :

rm *.o

Phony all

If no target is specified make executes the first explicit rule it finds.

It is common to name it “all”. This is usually used to build all possible programs that are in the makefile with just one make call.

all : prog1 prog2 prog3 .PHONY : all prog1 : prog1.o utils.o

cc -o prog1 prog1.o utils.o prog2 : prog2.o

cc -o prog2 prog2.o

Writing Rules

• A rule appears in the makefile and says when and how to remake certain files, called the rule's targets (most often only one per rule). It lists the other files that are the prerequisites of the target, and commands to use to create or update the target.

• The order of rules is not significant, except for determining the default goal: the target for make to consider, if you do not otherwise specify one. The default goal is the target of the first rule in the first makefile. If the first rule has multiple targets, only the first target is taken as the default. There are two exceptions: a target starting with a period is not a default unless it contains one or more slashes, `/', as well; and, a target that defines a pattern rule has no effect on the default goal. (See section Defining and Redefining Pattern Rules.)

• Therefore, we usually write the makefile so that the first rule is the one for compiling the entire program or all the programs described by the makefile (often with a target called `all'). See section Arguments to Specify the Goals.

Rule Syntax

• targets : prerequisites <tab> command <tab> ...