Example: a makefile for Separate Compilation¶
Suppose you are writing a C++ program that has the following files:
Student.h
: header file containing the declaration of theStudent
class and related functionsStudent.cpp
: the implementation of the methods and functions declared inStudent.h
Course.h
: header file containing the declaration of theCourse
class and related functionsCourse.cpp
: the implementation of the methods and functions declared inCourse.h
course_test.cpp
: some testing course forCourse
andStudent
, including amain
function
Here is a makefile that helps compile and link these files:
test: course_test.o Student.o Course.o
g++ -o test course_test.o Student.o Course.o # indent must be a tab
# only need to link if course_test.cpp has changed
course_test: course_test.cpp
g++ -c course_test.cpp # indent must be a tab
# only compile if Student.h or Student.cpp has changed since last compile
Student: Student.h Student.cpp
g++ -c Student.cpp # indent must be a tab
# only compile if Course.h or Course.cpp has changed since last compile
Course: Course.h Course.cpp
g++ -c Course.cpp # indent must be a tab
clean:
rm -f test course_test.o Student.o Course.o # indent must be a tab
# same compiler options as for the course makefile
CPPFLAGS = -std=c++14 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g
This makefile consists of 5 rules, and one variable (CPPFLAGS
) definition.
Consider this rule for create Course.o
:
Course: Course.h Course.cpp
g++ -c Course.cpp # indent must be a tab
The first line of the rule gives the rules name, Compile
, and then lists
the dependencies of this rule. In this case, the dependencies say that the
following statement only needs to run if Course.h
or Course.cpp
has
changed since the last compilation. This can be a great time-saver in large
programs: makefiles only re-run rules when necessary.
The second line of the rule is the code that will be run when the rule is
executed. In this rule, only one statement is run, i.e. Course.cpp
is
re-compiled. The compiler options listed in the CPPFLAGS
variable are
automatically included when g++
is called.
One annoyance with makefiles is that the indentation of the second line must be done with a tab character. If you use spaces for the indent, then you will get an error.
For this particular program, the programmer would usually call make test
like this:
$ make test
g++ -std=c++14 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g -c -o course_test.o course_test.cpp
g++ -std=c++14 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g -c -o Student.o Student.cpp
g++ -std=c++14 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g -c -o Course.o Course.cpp
g++ -o test course_test.o Student.o Course.o
This creates the executable file named test
, which you run like this:
$ ./test
CMPT 100 has this many students: 3
If you were to call make test
again without changing any of the .h
or
.cpp
files, you get this:
$ make test
make: 'test' is up to date.
Thanks to the rule dependencies in the makefile, make
realizes that there
is no need to re-compile or re-link anything.
Now suppose you course_test.cpp
to change the output message to CMPT has
?? students
. After making the change, you get this:
$ make test
g++ -std=c++14 -Wall -Wextra -Werror -Wfatal-errors -Wno-sign-compare -Wnon-virtual-dtor -g -c -o course_test.o course_test.cpp
g++ -o test course_test.o Student.o Course.o
$ ./test
CMPT 100 has 3 students
make
notices that only course_test.cpp
has changed, and so it only
needs to re-compile course_test.cpp
, and then re-link test
. There was
no need to re-compile Student.cpp
and Course.cpp
since they haven’t
change since the last time they were compiled.
Finally, the clean
rule in the makefile is used to get rid of all the
.o
files and test
:
$ make clean
rm -f test course_test.o Student.o Course.o
This is standard rule in most makefiles, and us used to clean up any files when you want to re-compile and re-link everything afresh.
Source Code¶
All the files for runing this example are here: separateComp.zip
.