Date post: | 15-Jan-2016 |
Category: |
Documents |
View: | 225 times |
Download: | 0 times |
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> ...