Compiling Your First Program

Before anything else, read chapter 2 of the book. Make sure you have a high level idea of how things work before getting into the details. To reiterate, we need to take our friendly (o.O) C++ code, and turn it into many, many teeny-tiny instructions that the computer understands. Instructions like, “take number x, add to number y, move result to memory address z”.

Okay – let’s see how it’s done. The first part of the process (compiling) is illustrated in a diagram on page 48 of the book. First, open up a terminal, and navigate to ~/tests/hello/, and then open your editor and create a file called helloworld.cpp (from the command line, $ edit helloworld.cpp will do the trick). Now type the following, and save the file:

1
2
3
4
5
6
7
8
#include<iostream>
using std::cout;

int main()
{
    cout << "Hello world.\n";
    return 0;
}

Since you have already read chapter 2, you know what the program does, and have a solid idea of each line’s significance. (If not, go back and read chapter 2, then start over.) Here, we just focus on the details of compilation. So let’s get to it. Step one: get back to the command line, and execute

$ g++ -c helloworld.cpp

Now look at the directory contents (ls) and note the presence of a new file, helloworld.o. This is the object code corresponding to the program you just wrote (see the graphic on page 48). The file helloworld.o contains the teeny-tiny instructions that make sense to the computer, but does not yet have the form of a complete working program that the OS can run, and only contains references to the functions that we used from elsewhere, e.g. all the stuff that makes cout work.1 To put everything together in a nice package (executable file) that can be run by the operating system, we must invoke the linker (see the diagram on page 51). This can be done as follows:

$ g++ helloworld.o -o hello

This will pull in all the needed references together with our object file and package it into an executable file called hello. Run ls, and you should see it sitting there. To run it, just execute $ ./hello, and you’ll see the message printed. Note: the ./ before the program name is essential, as the current directory probably is not in your search path.

Makefiles

A few observations:

We’ll see more of makefiles as the term progresses. You can read an introduction here, or here. At a high level, makefiles just contain recipes for how to construct the final executable from the source files, and the program make follows the recipe. (Note: you can use make for lots of other stuff besides just compiling C++!) The make program is pretty clever – it finds a sensible order in which to carry out the tasks, and it will check to see which files are out of date, so that it doesn’t perform any unnecessary work. The following is a (overly-simple) makefile you can use for your program. Download the original here, and place it in the same directory as the cpp file. (Note: makefiles are finicky about spaces vs. tabs, so if you type it instead, make sure to use tabs for indentation, and not spaces.)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
source = helloworld
output = hello
CC = g++
CFLAGS = -Wall -O2

$(output) : $(source).o
    $(CC) $< -o $(output)

$(source).o : $(source).cpp
    $(CC) $(CFLAGS) -c $<

.PHONY : clean
clean :
    rm -f $(output) $(source).o

This might look a little cryptic, but I’ve removed all the comments for brevity; download the original, and it will give you a better explanation of what’s going on. Anyhow, to run the makefile, you can simply type $ make at the command line (provided the current directory is the same as the location of the makefile). Give it a try! Delete the executable file hello and the object file helloworld.o, and then try

$ make

and notice that it built the program for you. Then, if you want to clean up all the extra files (the executable, as well as the object files) just run $ make clean and they’ll stop cluttering your directory.


Back to the 103 homepage


  1. Yes, even in a program this trivial and small, there are external dependencies! If you’re really curious, you can list them with nm -uC test.o.