CS170 Lab: C++ Separate Compilation and Makefile

Highlights of this lab:

The purpose of this lab is to show you how to compile a C++ program that is formed by several separate files. Makefiles simplify this process a great deal.

Lab Exercise:

Separate Compilation

Suppose you had a main function in the file main.cpp, and a function in the file myfunction.cpp. Further suppose that both main.cpp and myfunction.cpp each had a reference to the .h file myfunction.h. You would have to compile each of these files separately to produce .o files and then link them all together. The following commands show how to do this. Notice the -c option you need to specify when you want to compile only , not to compile and link.

Compile only: g++ -c main.cpp
Compile only: g++ -c myfunction.cpp
Link: g++  main.o   myfunction.o  -o main
Note that if you wanted to compile a whole set of C++ programs at the same time, you could enter: g++ -c *.cpp Be careful with this though, for these reasons:

Note that to link a whole set of object files you could have just entered: g++   *.o   -o main Again, you should be careful that you have all your files in one directory.

The following diagram illustrates how the previous example appears conceptually:

Building Executables with "make"

You can use the Unix utility called make to help you create an executable file from several C++ files. There are many other uses for make, but this lab focuses on how to use it to help simplify working with C++ files. Here is a list of references for using make: When you type make at the Unix/Linux command prompt, it looks for a file called Makefile or makefile which you would have created with a text editor. Inside the Makefile you have to put in the names of the C++ and object files that you need to create the executable file for the C++ project you are working with. Before we get into Makefile features such as targets, variables, and dependencies let's look at an example of how you would create a C++ project without a Makefile. We can then see how to make life simpler by using a Makefile to create that same C++ project.

Let's look at the files for a simple calculator project. The files are: Calculatr.cpp    DoMenu.cpp    GetOperands.cpp    AddNums.cpp    ModNums.cpp    Expon.cpp    and    Calculatr.h

Those steps just set you up to work with the files. You still need to compile the separate C++ modules and link them all together. Here are the steps to do that: Now everytime you make a change to one or two modules, you have to recompile those files and then perform the link again. And if you make a change to the .h file that all of those .cpp files depended upon, you have to recompile everything and do the link again. Of course you can just do this: but that is time-consuming and not at all necessary. It is much better to only compile the files you need to. This is where a Makefile can help you.

You have to be observe a little syntax when you create your Makefile with a text editor. Here are a few very simple rules:

This is a simple introduction to Makefiles. As you become comfortable with them you will find that you can elaborate with targets to clean up old .o files and so on. However, to start, here is a simple Makefile to deal with the Calculatr project.
# Makefile to create the Calculatr project

Calculatr.o:  Calculatr.cpp Calculatr.h
        g++ -c Calculatr.cpp

DoMenu.o:  DoMenu.cpp Calculatr.h
        g++ -c DoMenu.cpp

GetOperands.o:  GetOperands.cpp Calculatr.h
        g++ -c GetOperands.cpp

AddNums.o:  AddNums.cpp Calculatr.h
        g++ -c AddNums.cpp

ModNums.o:  ModNums.cpp Calculatr.h
        g++ -c ModNums.cpp

Expon.o:  Expon.cpp Calculatr.h
        g++ -c Expon.cpp

Calculatr: Calculatr.o DoMenu.o GetOperands.o AddNums.o ModNums.o Expon.o
        g++ Calculatr.o DoMenu.o GetOperands.o AddNums.o ModNums.o Expon.o -o Calculatr
Now that you understand what is in a Makefile you need to know how to use it. It's quite straightforward - simply enter make target at the system prompt. The make process will report on what it is doing. The following examples performed on the Venus computer illustrate how you to compile a single module, and how to link all files.
venus[24]% make DoMenu.o
        g++ -c DoMenu.cpp

venus[27]% make Calculatr
        g++ Calculatr.o DoMenu.o GetOperands.o AddNums.o ModNums.o -o Calculatr
If you enter a target that is already current, "make" reports that.
venus[22]% make DoMenu.o
`DoMenu.o' is up to date.
The bottom line here is that Makefiles help you work with multiple C++ files that make up a project. By only compiling the C++ files that you have to compile, you save a lot of time recompiling files needlessly. For greater detail on Makefiles, go back to any of the tutorials given at the start of this explanation.

Lab Exercise:

CS Dept Home Page
CS Dept Class Files
CS170 Lab Files
Copyright: Department of Computer Science, University of Regina.