CS247 Lecture 7
Last Time: Const Iterators, Templates, Separate compilation
This Time: Preprocessor, Makefiles, Tooling What is #ifndef
pattern?
The files we gave in A1 looked like:
Preprocessor directives - commands that allow transformations of the source code before it is compiled.
#include file
- replaces this line with the contents of file.
Consider an example: Linear Algebra Modules
We get a compilation error:
main.cc
includes Vec.h
main.cc
includes matrix.h
, includes Vec.h
Two definitions of struct Vec in main.cc
not allowed.
To fix this issue of multiple definitions, we use “include guards”:
#ifndef VARIABLE
The code between #ifndef
and #endif
will only be seen by the compiler if VARIABLE
is not defined.
#define VARIABLE
defines a preprocessor variable.
Include Guard:
Works because once File.h
is included once, the variable becomes defined, so in all future includes
the block is omitted.
Note
Doesn’t fix all issues! There is an issue with circular dependencies.
The issue is that each class needs to know the other exists before it can be created.
Solution: Break circular dependency chain using forward declarations.
Separate Compilation
Speeds up compilation and development time: change one .cc
file update the .o
file,
Issue: if we change a .h
file, then many .c
files might need to be recompiled. Mental energy to figure out the dependencies and just recompile the relevant .cc
files. Might be faster to just recompile everything.
Solution: Use a build automation system. Keep track of what files have changed, keep track of dependencies in compilation, and just recompiles the minimal number of files to make a new executable.
We’ll discuss make: Create a Makefile.
Example: main.cc
includes List.h
, List.h
, List.cc
includes List.h
Make v1: Need to identify the target and dependencies.
myprogram: main.o
List.o
- target: myprogram
- dependencies:
main.o
List.o
Target(TAB) is myprogram g++ main.o List.o -o myprogram
main.o
: main.cc
List.h
g++ -std=c++14 main.cc -c
List.o
: List.cc
List.h
`g++ -std=c++14 List.cc -c
This text is in a Makefile in our directory. make creates the first target Looks at the last modified time of dependencies. If last modified time is newer for a dependency than a target ⇒ target is out of date, recreate it.
Still too much work for me! Still requires lots of updates to our makefiles.
Make v2:
CXX=g++
- is a special Makefile variable for compiler we’re using.CXXFLAGS= -std=c++14 -Wall -g -MMD
-Wall
- more warnings-g
debuggingCXX=g++
is a special Makefile variable-MMD
supports
EXEC=myprogram
CCFILES=$(wildcard *.cc)
OBJECTS=${CCFILES:.cc=.o}
- find and replace string operation {}
DEPEND=${CCFILES: .cc=.d}
- include ${DEPENDS}
- compiles all object files with dependencies using
CXX
andCXXFLAGS
- compiles all object files with dependencies using
We’ve discussed a lot of programming ingl but we haven’t discussed methodology, other tooling yet.
Software development lifecycle:
Waterfall Method: client→ specs → program → build → Test/debug it → use source control → release it