Building on the Command Line

Compiling Your First Program

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”. Here is a pictorial summary of the process we are about to perform:

Fig. 1: Compiling and linking

Okay – let’s see how it’s done. The first part of the process is to compile your program into object code. First, open up a terminal (pressing alt+enter should do the trick in the virtual machine), navigate to ~/tests/hello/, and then open your editor and create a file called helloworld.cpp.1 Here are the two commands to accomplish the above steps:

$ cd ~/tests/hello/
$ edit helloworld.cpp

Now type the following into your editor, and save the file:

#include<iostream>
using std::cout;

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

If you had to guess what this program does, you’d probably be correct (it just prints “Hello world.”). We will talk at length about various language details, but for now we are mainly concerned with the details of compilation. So let’s get to it. Step one: get back to your terminal,2 and run the command ls. You should now see your new file:

$ ls
helloworld.cpp

Great. Now let’s turn that thing into a runnable program:

$ g++ -c helloworld.cpp

Now look at the directory contents again and note the presence of a new file, helloworld.o:

$ ls
helloworld.cpp   helloworld.o

This is the object code corresponding to the program you just wrote. 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.3 To put everything together in a nice package (executable file) that can be run by the operating system, we must invoke the linker. This can be done as follows:4

$ 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 yet again, and you should see it sitting there (should be colored green):

$ ls
hello  helloworld.cpp  helloworld.o

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.

Congratulations, you’ve compiled and run your first C/C++ program!

Note: in the simplest of cases (which the above program epitomizes), you can just run the command

$ g++ helloworld.cpp

This will compile and link all in one step, and produce a runnable program named a.out by default. It’s fine to use this instead, but I want the distinction between compiling and linking to be clear in your mind, which is why I’ve shown you the separate steps first. If you are interested to learn about streamlining more complex compiling processes read the section below.

Makefiles (optional!)

Note: you don’t need to understand this in any detail. The TL;DR version (“makefiles run g++ for me”) is all you really need to know. Read more if you are curious, though.

A few observations:

We’ll see more of makefiles as the term progresses. You can read an introduction 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.)

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. If not on the virtual machine, you can make this directory using the command mkdir -p ~/tests/hello.↩︎

  2. You can press alt+<arrow key> to navigate to different windows, or just place the mouse over the window you want to be focused (you don’t even have to click).↩︎

  3. 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.↩︎

  4. It may be confusing that the same command (g++) is being used to compile and link. It turns out g++ is really just a wrapper for a handful of other tools (including a linker, called ld). The g++ command figures out what to do in part based on the arguments you give it, and by default ultimately tries to produce an executable.↩︎

  5. Although you will typically only need a small handful.↩︎