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.
C++ Introductory Assignment
Makefile Assignment



C++ Introductory Assignment

Your assignment will require you to make three files: 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 <TAB> 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:
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.