Notes on writing C++ programs with the gnu compiler

To do anything but the smallest `hello world' program, it is good programming style to break your program into several pieces (files) and compile and test them separately before compiling the final program (in reality, there is no final program). This meshes very well with the way we do mathematical research, or solve mathematical problems at any level -- we break the problem into smaller problems  which we solve separately and then construct the solution to the original problem from the pieces.

We are using the gnu compiler gcc to compile our C++ programs, mainly because it is freely available and it is very satisfactory for our purposes.

The compiler options -c and -o file

The gnu compiler gcc (or g++) has two options that we use a lot when compiling our program in pieces.

The compile option -c This is used on a single source (.cpp) file to construct an objective file (.o) with the same name. If we have a source file called bisect.cpp (implementing the bisection method for solving an equation) that we want to compile, the command

g++ -c bisect.cpp

will set the compiler off on the task of trying to create a compiled version which it calls bisect.o . (Note: If you are using the C++ compiler from the Chisel disk, the gnu compiler name is gcc, rather than g++.) Of course, there will probably be errors in the program the first time. But with persistence, you will soon have a bisect.o . Then what? Well, you need a main.cpp to test out bisect.o . This would be compiled separately with the command

g++ -c main.cpp

You only compile one .cpp file at a time with the -c option.

Now the second option comes in when you want to compile an executable file:

The compile option -o file : Use this option to link your .o files into an excutable file called file . So, to compile an excutable program called roots which tests the bisection method, give the command

g++ -o roots main.o bisect.o

There may be compiler errors here too. If you are using the compiler on the Chisel disk, you need to load the library gpp or there will will be errors. So, the command there reads

gcc -o roots main.o bisect.o -lgpp

Now if everything went well, we can just say the word roots to run the program.

Of course, even if the program runs, there probably will be changes for you to put in. So you will find yourself issuing the same sequence of commands over and over. This is where the program make comes in handy.

Using make to manage your project

The program make was written to simplify the development of a program that you are working on. Most programmers use it or something like it to develop projects. A simple makefile to work on the project roots would look something like this.

# a makefile for the project roots

roots : main.o bisect.o

<tab> g++ -o roots main.o bisect.o

main.o : main.cpp

<tab> g++ -c main.cpp

bisect.o : bisect.cpp

<tab> g++ -c bisect.cpp

clean :

<tab> rm roots main.o bisect.o

This would be put in a file makefile in the directory with the source files, and from there the command make roots would compile any files that had been changed since the last time the command was issued. If you want to start over, you would issue the command make clean .

Creating libraries of procedures with the program ar

Suppose we have written and tested some other rootfinding methods, say Newton's method ( newton.cpp ) and the secant method ( secant.cpp ). At that point, we might want to start a library of compiled procedures with these three. This can be done with the command

ar ru mylib.a bisect.o newton.o secant.o

ar is a program which archives procedures, ru is an option meaning replace and update, mylib.a is the name we have chosen for our library, and the three .o files have been compiled already.

Problem . There is a zipfile here called roots.zip which contains files to get you started on building the library mylib.a. Download it and unzip it. Finish the task by writing, compiling, and testing newton.o and secant.o. Then add newton.o and secant.o to the library. Document the source .cpp file with a description of the algorithm and its syntax.