1 the makefile utility abc – chapter 11, 483-489
Post on 19-Dec-2015
221 views
TRANSCRIPT
1
The Makefile Utility
ABC – Chapter 11, 483-489
2
Motivation
• Small programs single file
• “Not so small” programs :– Many lines of code– Multiple components– More than one programmer
3
Motivation – continued
• Problems with a single-file program:
– Long files are harder to manage(for both programmers and machines)
– Every change requires long compilation– Many programmers cannot modify the
same file simultaneously
4
Motivation – continued
• Solution : divide project to multiple files
• Target: good division to components– Easy maintenance of project structure, dependencies and creation– Minimum compilation when something is changed
5
Project maintenance
• Traditionally is done in Unix by the Makefile mechanism
• A makefile is a file containing :– Project structure (files, dependencies)– Instructions for files creation (*.o, executable)
• The make command reads a makefile, understands the project structure and makes up the executable
• Note that the Makefile mechanism is not limited to C programs
6
Project structure
• Project structure and dependencies can be represented as a DAG (= Directed Acyclic Graph)
• Example :– Program contains 3 files– main.c., sum.c, sum.h– sum.h included in both .c files– Executable should be the file sum
7
sum (exe)
sum.omain.o
sum.h sum.cmain.c
8
makefile
sum: main.o sum.o
gcc –o sum main.o sum.o
main.o: main.c sum.h
gcc –c main.c
sum.o: sum.c sum.h
gcc –c sum.c
Rule
Rule
Rule
9
Rule syntax
main.o: main.c sum.h
gcc –c main.c
Tab!!! Action(s)
TargetDependencies
Rule
10
*.o: *.c dependencies• An *.o file depends (by default) on the
corresponding *.c file - if NO action is specified – Example: foo.o: foo.h
The implicit action is : $(CC) -c foo.c -o foo.o
sum: main.o sum.ogcc –o sum main.o sum.o
main.o: sum.hgcc –c main.c
sum.o: sum.hgcc –c sum.c
ERROR: main.o won't compile when main.c is more recent!!!
touch - updates the timestamp
11
Additional info on makefile rules
• A Rule can have multiple targets– Useful when several targets share
dependencies/actions
• A Rule can have no action (only defines dependencies)
• A target can appear in multiple Rules. However a target should have at most one rule with an action
• A rule can have an empty set of dependencies– Example: the target clean – has an empty set of
dependencies. Used to clean intermediate files.
12
Equivalent makefiles
• We can compress identical dependencies and use built-in macros to get another (shorter) equivalent makefile :
OBJS = main.o sum.osum: $(OBJS)
gcc –o $@ $(OBJS)
%.o: %.c sum.hgcc –c $*.c
Variable definition
Accessing a variable
$@ = the target (automatic variable)
pattern ruleEvaluates to the current
*.c file
13
make operation
• Project dependencies DAG is constructed• Target of first rule should be created• We go down the DAG to see if there is a
target that should be recreated. This is required when the target file is older than one of its dependencies
• In this case we recreate the target according to the action specified, on our way up the tree. Consequently, more files may need to be recreated
• If something was changed, linking is performed
14
make operation - continued
• make operation ensures minimum compilation, when the project structure is written properly
• Do not write something like:prog: main.c sum1.c sum2.c
gcc –o prog main.c sum1.c sum2.cwhich requires compilation of all projectwhen something is changed
15
Make operation - example
File Last Modified
sum 10:03 main.o 09:56sum.o 09:35main.c 10:45sum.c 09:14sum.h 08:39
Which targets will be recreated?
16
Make operation - example
• Operations performed:
gcc –c main.cgcc –o sum main.o sum.o
• main.o should be recompiled (main.c is newer).
• Consequently, main.o is newer than sum and therefore sum should be recreated (by re-linking).
17
Automatic generation of dependencies
• Using the precompiler– gcc -MM file.c– gcc -MM *.c
18
Useful gcc Options
• Include: -I<path>• Define: -D<identifier>• Optimization: -O<level>
Example: gcc –DDEBUG –O2 –I/usr/include example.c –o example -lm
19
Another makefile exampleCOMMON_DIR = ../commonC_FILES = $(COMMON_DIR)/file1.c $(COMMON_DIR)/file2.c main.cOBJ_FILES = $(patsubst %.c,%.o,$(C_FILES))CFLAGS = -Wall -g -ansi -pedantic-errors -DNDEBUGCC = gccINCLUDES = -I$(COMMON_DIR)
modularity_mat: $(OBJ_FILES)$(CC) $(CFLAGS) $(OBJ_FILES) -lm -o $@
%.o:%.c$(CC) $(CFLAGS) $(INCLUDES) -c $*.c -o $*.o
clean:-rm $(OBJ_FILES) modularity_mat
depend:@echo -e '\n' >> makefile$(CC) $(INCLUDES) -MM $(C_FILES) >> makefile
Pattern substitution string function: $(patsubst pattern, replacement, text)
adding dependencies to the makefile
20
Another makefile exampleCOMMON_DIR = ../commonC_FILES = $(filter-out %main.c,$(wildcard $(COMMON_DIR)/*.c)) main.cOBJ_FILES = $(patsubst %.c,%.o,$(C_FILES))CFLAGS = -Wall -g -ansi -pedantic-errors -DNDEBUGCC = gccINCLUDES = -I$(COMMON_DIR)
modularity_mat: $(OBJ_FILES)$(CC) $(CFLAGS) $(OBJ_FILES) -lm -o $@
%.o:%.c$(CC) $(CFLAGS) $(INCLUDES) -c $*.c -o $*.o
clean:-rm $(OBJ_FILES) modularity_mat
depend:@echo -e '\n' >> makefile$(CC) $(INCLUDES) -MM $(C_FILES) >> makefile
string functions: $(filter-out pattern,text) $(patsubst pattern,replacement,text) $(wildcard pattern)
adding dependencies to the makefile
all C files under $(COMMON_DIR), except files whose names ends with main.c
21
Reference
• Good tutorial for makefiles http://www.gnu.org/software/make/manual/make.html
http://www.cs.huji.ac.il/course/2005/labc/lectures/f_make.pdf