2. Setting Up Your Linux Environment

Before diving into C++ programming, we need to spend some time setting up our program environment. In this course the programming environment is Linux, and we assume you will be using a text editor to edit your programs and command-line window to compile and run them. You can certainly use other tools if you wish, but we can’t promise to help you with them.

2.1. Getting Linux

If you want to use Linux on your own computer — something we strongly recommend! — then we recommend you install Ubuntu Linux. That’s the version of Linux we’ll be using in the lectures and labs.

Here are some options for running Ubuntu on a Windows computer:

  • Try Wubi. This may be the easiest way to get Ubuntu running on Windows.

  • Run Ubuntu as a virtual machine on a Windows computer using, for instance, VirtualBox. Then you can run an entire Linux system as a regular Windows program in its own window.

    If you want to try this, start by looking at the VirtualBox End-user documentation.

  • Dual-boot your PC to run both Windows and Linux.

  • Install Ubuntu on a CD or USB drive, and then run Ubuntu from that.

  • Install Ubuntu on a spare computer.

See the Ubuntu download page, or the Ubuntu Installation Wiki page, for (much) more information.

If you are using a Mac, then, because it is already a Unix-based (although not Linux) system, and XCode is what you should use.

2.2. Using the Command-line Window

Most of what we will do in this course can easily be done with a command-line window, sometimes called a shell window. The command-line window lets us type commands to run programs.

By default, command-line windows in Ubuntu uses the BASH command-line, and when you first launch it you will see a prompt something like this:

tjd@tjd-ubuntu-desktop:~/cmpt125$

This prompt has a lot of parts:

  • tjd@tjd-ubuntu-desktop is the user name and computer name. This is useful when you are using multiple computers or multiple accounts.
  • ~/cmpt125 is the current working directory, i.e. the directory that the command-line will look in first when you run a program. The ~ is shorthand for you personal directory.
  • $ marks the end of the prompt and the beginning of where the user types commands. In these notes we will usually denote the shell prompt using just a $.

Note

It turns out that command-line prompts are highly customizable (e.g. see this posting as a start). You are curious you can configure your prompts to provide lots of useful information.

2.3. Some Useful Shell Commands

The shell has dozens and dozens of commands, although to get started you only need to know a few simple ones. Here is a brief summary of the commands we’ll discuss here:

Command Summary
pwd returns present working directory
ls lists files and folders of pwd
cd change the pwd
rm delete a file
cp copy a file
man print a manual page
less print contents of a file
  • pwd prints the present working directory, e.g.:

    $ pwd
    /home/tjd/cmpt125

    The present working directory is also sometimes called the current working directory.

  • ls and ls -l list all the files and folders in the present working directory, e.g.:

    $ ls
    a1/  readme.txt
    
    $ ls -l
    total 8.0K
    drwxr-xr-x 2 tjd tjd 4.0K 2011-12-01 16:15 a1/
    -rw-r--r-- 1 tjd tjd   30 2011-12-01 16:15 readme.txt

    In this example, a1 is a folder, and readme.txt is a file.

  • cd changes the current working directory, e.g.:

    $ ls
    a1/  readme.txt
    
    $ cd a1
    
    $ pwd
    /home/tjd/cmpt125/a1
    
    $ cd
    
    $ pwd
    /home/tjd

    Note that cd on its own returns you to your home directory.

    cd .. changes the current working directory to be the parent of the directory the shell is in now. Running cd .. multiple times in a row is an easy way to “walk up” a folder structure to some top-level folder.

  • rm deletes a file. For example, suppose temp.txt is in the current directory. Then this command deletes it forever:

    $ rm temp.txt

    Beware that rm truly deletes the file: it does not put the file in the desktop trash!

  • cp makes a copy of a file. For example, suppose a1q1.cpp is in the current directory. Then this command makes a copy of it called a1q1.cpp.old:

    $ cp a1q1.cpp a1q1.cpp.old
  • man prints a help page (called a manual page, or man page for short) for a command. For example, ls many options:

    $ man ls
    LS(1)                            User Commands                           LS(1)
    
    NAME
           ls - list directory contents
    
    SYNOPSIS
           ls [OPTION]... [FILE]...
    
    DESCRIPTION
           List  information  about  the FILEs (the current directory by default).
           Sort entries alphabetically if none of -cftuvSUX nor --sort.
    
           Mandatory arguments to long options are  mandatory  for  short  options
           too.
    
           -a, --all
                  do not ignore entries starting with .
    
           -A, --almost-all
                  do not list implied . and ..

    This only shows the first few lines of the ls man page: ls has lots of options!

    Note that for some commands man is not helpful, e.g.:

    $ man cd
    No manual entry for cd

    Commands like cd are part of the BASH shell language, and there are no man pages for shell commands. However, if you type man bash, then you will get (a very long) man page documenting all the BASH commands (including cd).

  • less displays the contents of a text file:

    $ less helloworld.cpp
    // helloworld.cpp
    
    #include <iostream>
    
    using namespace std;
    
    int main() {
      cout << "Hello, world!\n";
    }

    If the file being displayed doesn’t fit on the screen, then a single page of the file is displayed at a time. Press:

    • spacebar to go to the next page
    • b to go the previous page
    • q to quit less immediately
    • /banana to search for the string banana

Note

You can also manipulate files and folders interactively in the GUI. Just open the folder you want to change, and use the typical drag-and-drop actions you are probably already familiar with.

In practice, it is sometimes easier to use the GUI instead of the command-line. For example, copying a folder it is easier in a GUI.

Sometimes the command-line is best. For example, if you want to delete all the files ending with .bak, then you can type this:

$ rm *.bak

The * is a special meta-character that matches any string of characters, and so *.bak matches all file names ending with .bak.

2.4. Using g++ in Linux

In this course we’ll be using the GNU C++ compiler, aka g++, throughout the course. We recommend you use it too.

Note

You are, of course, free to use any other standards-compliant C++ compiler you wish, but we can’t promise to provide help with compilers other than g++. Keep in mind that different compilers will also have different error messages, options, and bugs.

Warning

Your assignments will be marked by compiling and running them on Linux. It is your responsibility to make sure your programs compile and run correctly in Linux. If your assignment does not compile and run on Linux, the TA may not mark your assignment.

To test if g++ is installed on your computer, type g++ at the command-line:

$ g++
g++: no input files

If you see a message like “g++: command not found”, then you will need to install g++. The easiest way to do this in Ubuntu is to type this command (you’ll be asked to enter your password):

$ sudo apt-get install g++

After this finishes downloading and installing, test it by typing g++ as above.

Note

Another way to install software on Ubuntu is to use the Synaptic Package Manager program that comes with it (look for it in the System menu). This is essentially a graphical shell for the apt-get program that makes it much easier to search for, and select, the software you want.

2.5. Editing C++ Files

C++ programs are stored as text files that end with .cpp (or sometimes .cc) and .h. These are ordinary text files that you can edit with any text editor. Ubuntu has a number of text editors you might want to try:

  • Sublime Text 2 is a new editor that is quickly gaining in popularity due to its useful feature set and good performance. It’s currently free, and runs on Windows, Mac, and Linux systems. Technically it is not free, however you can freely evaluate the complete editor for as long as you like. You can download it from here.

  • Kate is a good programming editor for Linux that is quite easy to start using. On Ubuntu, it is available for download through the “Ubuntu Software Centre”, or by running the command in a terminal window:

    $ sudo apt-get install kate
  • emacs is a very old but still very popular text editor designed for programmers. It’s easy to run:

    $ emacs hello.cpp

    Note

    If emacs is not on your Ubuntu system, you can install it by typing this command:

    $ sudo apt-get install emacs

    Out of the box, emacs has excellent support for C++ programming, including syntax-coloring, bracket-matching, and GDB debugger integration. It also has special modes for writing makefiles, editing plain text, and so on. It can even do things like read your email, browse the web, and play games.

    Emacs extremely customizable, with hundreds and hundreds of add-ons available for it.

    Emacs comes with lots of documentation and help, and it’s relatively easy to use right away. However, it has quite a steep learning curve and so is probably best for programmers who plan to use it frequently and for a variety of different editing applications.

  • vim (or vi) is another very old but still extremely popular programming editor:

    $ vi hello.cpp

    Like emacs, vim has good support for programming out of the box, and it also extremely customizable with lots of add-ons already written.

    vim uses a modal style of editing which is different than emacs and other text editors. This takes some getting used to since you can’t just start typing in vim: you need to first selection a text-entering mode. Once you get used to it and learn a few commands, vim may be the fastest editor around. It loads very quickly (in contrast to emacs and IDEs) and experienced vim users can do amazing things in just a few keystrokes.

    Note

    Vim and emacs users often have “religious wars” about which editor is better. Ultimately, either editor is fine, and you might want to give both a try. The important thing is that you take some time to learn the features of a good programming editor: you will be a better and more efficient programmer if you do.

  • Bluefish is a more modern-looking editor that provides good support for a number of programming languages. To install it type this at the command-line:

    $ sudo apt-get install bluefish
  • gedit is a relatively simple text editor that works much like Notepad on windows. It should be installed by default, and you use like this:

    $ gedit hello.cpp

    While you can certainly use gedit to write C++ programs, we don’t recommend it. gedit is designed for editing regular text files, and doesn’t provide as many special features for writing code that the editors below do.

  • Integrated development environments, such as Eclipse or Code::Blocks, are popular with many programmers. Eclipse, for instance, works well with many programming languages.

    As with any programming editor, it takes time and effort to learn all the useful features of an IDE. Eclipse, for instance, has hundreds of features and tools.

    Another issue with IDEs is that they hide many of the lower-level details of the software creation process that are useful to know about. Thus, we recommend for this course that you don’t use an IDE, and instead use just a programming editor and the command-line to edit and create your programs. You’ll not only learn more about the software creation process, but you may even find it sometimes preferable to using an IDE.

2.6. Compiling a Program with make

Now lets see how to compile and run a C++ program. Cut-and-paste the following into a file called helloworld.cpp:

// helloworld.cpp

#include <iostream>

using namespace std;

int main() {
  cout << "Hello, world!\n";
}

Save the file, and then in the same directory type the following command:

$ make helloworld
g++     helloworld.cpp   -o helloworld

Note

If make is not on your Ubuntu Linux system, then install it using this command:

$ sudo apt-get install make

This compiles helloworld.cpp and creates an executable file called just helloworld:

$ ls
helloworld*  helloworld.cpp

To run the executable file, type this:

$ ./helloworld
Hello, world!

Notice you must put ./ in front of the executable file name. This is a simple safety precaution to avoid accidentally running an executable file.

Something interesting happens if you try to re-compile the program:

$ make helloworld
make: `helloworld' is up to date.

The make program is smart enough to know that the executable file already exists, and so there is no reason to compile it again. It knows this by checking the time-stamps on the files: the last change to helloworld.cpp was before the creation of of helloworld, and so there is no need to re-compile it. In other words, make only re-compiles a program if it has changed since the last compilation. For large projects consisting of 100s, or even 1000s, of files, make can dramatically decrease the compile time.

If you didn’t enter the program correctly, you might get an error message. For example, suppose we forgot the second ;:

// helloworld.cpp

#include <iostream>

using namespace std;

int main() {
  cout << "Hello, world!\n"   // oops: forgot a semi-colon
}

Here’s what happens when you try to make it:

$ make helloworld
g++     helloworld.cpp   -o helloworld
helloworld.cpp: In function ‘int main()’:
helloworld.cpp:9: error: expected ‘;’ before ‘}’ token
make: *** [helloworld] Error 1

If you read this error message carefully you’ll see that it refers to line 9 of the program, i.e. the last line of the program (that has a } on it).

Unfortunately, error messages in C++ are often messy and perplexing. One of the difficulties of generating good error messages is that the line where the program fails might not be the same line as where the error is located. For instance, in the error above the point of failure is line 9, but the error is located on line 8.

2.7. Compiling Without make

If you prefer, you can run g++ directly when you compile your programs. For example:

$ g++ helloworld.cpp

This creates an executable file called a.out which you can run like this:

$ ./a.out
Hello, world!

If you want the executable file to be named something other a.out, use the -o option:

$ g++ helloworld.cpp -o hello

$ ./hello
Hello, world!

Unlike using make, compiling directly with g++ always re-compiles the source file, even if it hasn’t changed. That doesn’t make much difference for small programs, but for large multi-file C++ programs you’ll soon discover that unnecessary re-compilation can eat up a huge amount of time.

2.8. Using make with a Simple Makefile

Another useful thing to do with make is to include a makefile that sets the options we want to use to compile our programs. For example, the g++ compiler has an option called -Wall that turns on all warnings. This is often a useful way to help you find bugs in your code. Also, if you want to use a debugger (such as gdb) to examine your executable programs, you need to compile them with the -g option.

So to use these options, create a file called makefile in the same directory as a1q1.cpp and put the following into it:

# set the C++ compiler options
# -Wall turns on all warnings
# -g puts debugging info into executables (makes them larger)
CPPFLAGS = -Wall -g

CPPFLAGS is a special pre-defined make variable that is meant to contain the options we want to pass to the C++ compiler. Lines that begin with a # character are comments to the reader of the makefile.

Now when you make a1q1 it uses the options listed in CPPFLAGS:

$ make a1q1
g++  -Wall -g   a1q1.cpp   -o a1q1

2.9. Speeding Up make

If your computer has more than one CPU (quite common these days), then you can try running make with the -j option:

$ make -j

This will cause make to try to use multiple CPUs to make your programs. This can significantly speed up compile times when more than one program is being compiled. Of course, if make is only compiling a single program then the -j option isn’t useful (but it doesn’t usually cause any problems).

2.10. Optional: Automatically Generating Dependency Rules

Note that the compiler can generated makefile rules for you using the -MM option:

$ g++ -MM a1q1.cpp
a1q1.o: a1q1.cpp std_lib_cmpt125.h

While we won’t be using this feature in this course, it can be useful for large projects where it might not be at all obvious what the makefile dependency rules should be.

2.11. Questions

  1. Briefly explain what each of the following BASH shell commands do: pwd, ls, cd, rm, cp, man, less.
  2. Why is a non-programming text editor such as gedit not a good way to edit programs?
  3. Suppose the file matrix.cpp is in the current working directory. What would you type at the command-line to create an executable called matrix using make? What about using g++ directly?
  4. What are two advantages of using make instead of directly using g++?
  5. How would you install make on Ubuntu Linux if it was not already installed?
  6. What does the -j option do for make?