COMP2521
Data Structures & Algorithms
Week 1.3
Compilation & Makefiles
1
In this lecture
Why?
Compilation in the real world isn’t as straightforward as
you were led to believe in 1511
What?
GCC compilation
make & Makefiles
2
Compilers
Compilers are programs that:
convert program source code to executable form
“executable” might be machine code or bytecode
The Gnu C compiler (gcc):
applies source-to-source transformation (pre-processor)
compiles source code to produce object files
links object files and libraries to produce executables
Note that dcc and 3c are wrappers around gcc:
Providing more checking and more detailed/understandable error messages
Better run-time support (e.g. array bounds, use of dynamic memory)
Not suitable to prepare you for the real world
3 . 1
GCC Compilation Stages
For a single file
-E: Pre-processor
-c: Compiles C code
-o: Links to make executables
3 . 2
GCC Compilation Stages
For multiple files
3 . 3
GCC Compilation Stages
gcc -c Stack.c
# produces Stack.o, from Stack.c and Stack.h
gcc -c bracket.c
# produces bracket.o, from bracket.c and Stack.h
gcc -o rbt bracket.o Stack.o
# links bracket.o, Stack.o and libraries
# producing executable program called rbt
1
2
3
4
5
6
7
GCC includes
3 . 4
Makefiles
For very large projects, compilation can get complex:
Have to run many commands, or long commands
If not careful, ends up recompiling EVERYTHING instead of
only the files that have changed.
If we only modify file1.c, the X is unnecessary.
file1.c
file2.c
file1.o
file2.o
./program
X
4 . 1
Makefiles
For our previous compilations, we can now define a file that
tells GCC how to keep track of dependencies for compilation
$ make1
make compiles code, driven by dependencies defined in a Makefile.
The target is rebuilt if older than any source (applied recursively)
target: source1, source2 …
commands to build target from sources (indented with a tab)
target: source1, source2 …
commands to build target from sources (indented with a tab)
target: source1, source2 …
commands to build target from sources (indented with a tab)
1
2
3
4
5
6
7
8
4 . 2
Makefiles
Sources can also be targets
rbt : brackets.o Stack.o
gcc -o rbt brackets.o Stack.o
brackets.o : brackets.c Stack.h
gcc -Wall -Werror -c brackets.c
Stack.o : Stack.c Stack.h
gcc -Wall -Werror -c Stack.c
clean :
rm -f *.o rbt
1
2
3
4
5
6
7
8
9
10
11
12
$ make1
make compiles code, driven by dependencies defined in a Makefile.
The target is rebuilt if older than any source (applied recursively)
4 . 3
Makefiles
Makefiles can contain variables
CC=gcc
FLAGS=-Wall -Werror
rbt : brackets.o Stack.o
$(CC) -o rbt brackets.o Stack.o
brackets.o : brackets.c Stack.h
$(CC) $(FLAGS) -c brackets.c
Stack.o : Stack.c Stack.h
$(CC) $(FLAGS) -c Stack.c
clean :
rm -f *.o rbt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ make1
4 . 4