UMBC CMSC 202 Computer Science II
Lab2: Introduction to C++ and Makefiles
In this lab, you will write a simple program to introduce you to C++, in particular strings, vectors and simple input and output. Also, Makefiles will be introduced.
Discussion
C++ Introductory Assignment
Makefile Assignment
Discussion
Topics:
- Similarities with C - loops, conditionals, just about everything
- A C++ Example with strings and vectors (code)
- Makefiles - what they do, how they help
C++ Introductory Assignment
Your assignment will require you to make three files:
- lab2.cpp - contains main, that you will write. It includes lab2function.h.
- lab2function.h - contains the prototype of the function you will write (reverse).
- lab2function.cpp - contains the implementation of the function you will write (reverse). It includes lab2function.h.
Assignment: Write a simple program reads words into a vector, like the example application. Then, write a reverse function that
takes in a sting as a parameter and returns a string that is the reverse of the one passed. Next, in main, iterate
through each string in the list and print out (cout) the reverse of each.
Makefile Assignment
Makefiles are instructions for the operating system, telling it how to compile
your program. In this course, you will be required to use multiple files
and compile them together. You will also be required to ensure that the
correct compiler will be used to compile each file. The GL systems actually
have two different g++ compilers installed. Using the wrong version may
prevent your project from compiling either for you or the graders. There are
several Resources on Makefiles available on the Resources page, so be sure
to read through them on your own time. In this lab, you will be learning the
basics of Makefiles.
First, makefiles should be named 'makefile' or 'Makefile'. There is no
extension for a makefile, and the 'm' can be capitalized.
There are four primary components to a makefile:
-- Variables - (like macros) allow us to more easily make modifications
-- Targets - gives a name to a command, allows us to run that command from
the command prompt
-- Dependencies - list of files or targets that must be recompiled if
updated
-- Command - one or more commands associated with a single target that are the
"jobs to run" for that target
Let's take a look at the format for a simple makefile:
MACRO_NAME = VALUE
TARGET : DEPENDENCIES
COMMAND
Here is an example makefile that follows this format:
Lab2 : lab2.cpp
/usr/local/bin/g++ -g -Wall -ansi -o Lab2 lab2.cpp
You should notice that the < TAB > has been replaced with an actual tab, UNIX
makefiles require this tab or else it will not recognize the command as
related to the target.
The target in this example is 'Lab2', you should also notice that Lab2 will
be the executable name as it follows the '-o' switch (this indicates what the
output should be named to the g++ compiler). The '-g' switch indicates that
debugging flags should be turned on - this will enable you to use the UNIX
debugger (either gdb or ddd). The '-ansi' flag indicates that ansi-standards
should be turned on. The '-Wall' flag communicates with the assembler and
linker. You should always use these three flags to ensure proper compilation
of your project. You should also notice that the compiler we are using is
located in /usr/local/bin, it is necessary that you force compilation using
this compiler, otherwise, your project may not compile due to compiler
differences and incompatibilities.
To simplify your makefile, you can use variables to substitute for components
of targets, dependencies, and commands. In this variation of the above
makefile, we use these variables to get rid of the compiler, flags, and
project name.
COMPILER=/usr/local/bin/g++
CFLAGS=-g -Wall -ansi
PROJECT=Lab2
$(PROJECT) : lab2.cpp
$(COMPILER) $(CFLAGS) -o $(PROJECT) lab2.cpp
You should notice that we indicate a variable replacement by using $() around
the variable name. Everything is text-based in a makefile, so you can replace
any text with a variable. Also, makefiles are line-based, a command must fit
on a single line, or indicate extension to the next line with the backslash '\'
character.
One thing that we will use consistently in this course is compiling multiple
files into a single project. One rule is that you should have a target and
command pair for each file you will be compiling. Only one target will have
a command that includes the '-o' flag while all of the other commands should
have the '-c' flag. In the following example, lab2function.cpp has several
functions that are used by the lab2.cpp main function. The makefile would
look like so:
COMPILER=/usr/local/bin/g++
CFLAGS=-g -Wall -ansi
PROJECT=lab2
$(PROJECT) : lab2.cpp lab2function.o
$(COMPILER) $(CFLAGS) -o $(PROJECT) lab2.cpp lab2function.o
lab2function.o : lab2function.cpp
$(COMPILER) $(CFLAGS) -c lab2function.cpp
You should notice several things here - one of the PROJECT dependencies is
'lab2function.o', which will force the operating system to run the 'lab2function.o'
rule whenever it needs updating. Also notice that 'lab2function.o' has been
added to the COMPILER line for the PROJECT rule - this will tell the compiler
that the 'lab2function.o' file has code that is needed by 'lab2.cpp'.
One final note about makefiles, you can make any target in the entire file
by typing:
make TARGET
For example, if we want to make the entire project, we simply type:
make lab2
Making only 'lab2function.o' can be done by:
make lab2function.o
Also, by default, just using make will make the first target in the
project.
Assignment: Create a makefile that will correctly compile your C++ assignment from the first part of the lab.