The GNU G++ Compiler

There are many different C and C++ compilers for UNIX environments. Most of these are specific for a particular architecture and operating system. The fine folks in the GNU project have created a C/C++ compiler that has been ported to many different architectures. The name of the compiler is gcc or g++ for the C or C++ compiler respectively. Because of the similarities between C and C++, the two commands actually call the same compiler with different default options. Because of the similarity, the rest of this document will talk exclusively about g++. The discussion will automatically apply to gcc unless stated otherwise.

Creating an executable program is a two step process. First the source code is compiled to object code. The object code may or may not be stored as a separate file, depending on the compiler used and the compiler options. Second, the object code is linked with other collections of object code (including system libraries) to form an executable file.

The GNU g++ compiler can be used to control both the compilation phase and the linking phase of creating executable files.

Options

Like most UNIX commands, g++ has numerous options. The most useful of these are

-v
Prints out the version of the compiler. This option is usually used by itself.
-c
Compiles source code files to object files and stops. The default behavior of the compiler is to compile the given source code files and link them directly into an executable file. The -c option is useful for efficiently making projects that have multiple source code files.
-o filename
Specifies the name of the output file. Without this option, executable files have the default name of a.out. The default name of an object file is the same as a source code file, but with a .o extension replacing whatever source code extension existed.
-O
Turns on optimization. Allows the compiler to modify the code as it's compiling and linking to produce smaller and/or faster files. The results are (hopefully) functionally equivalent to the program without optimization. In practice optimizer bugs do occur. Recognizing things that can be optimized is actually rather difficult and is not always done correctly. Because of this, optimizing should be the last thing done to a program. Once a program works without optimization, then the optimizer can be used to try to improve the program. If the program doesn't work, then the optimizer can be blamed.

(It's a computer science joke that compilers also contain a pessimizer that breaks your code and introduces bugs. Unfortunately, nobody has been able to find the flag that turns this feature off.)

-g
Turns on code generating options for debugging. Detailed information is stored in the object files and executable files about which lines in the source code file are associated with the machine code instructions. This can make programs comparatively large and slow. However, this information is used by a debugger to allow stepping through a program line by line as it executes, which is very useful. The -g option is incompatible with the -O option. They should not be used together.
-Wall
Turn on all the warning messages possible. Most useful during the compilation phase, but also works during the linking phase.
-Idirectory_name
Use the given directory as a place to search for include files. This directory is used in addition to the standard system include directories. Multiple include directories are specified by using a separate -I option for each directory. There is no space between the -I option and the directory name.

The standard directories used by a compiler are usually built in to the compiler and may vary from machine to machine, but /usr/include is often one of the standard directories.

This option is useful only during the compilation phase.

-llibrary_name
Link the given library into the program. A library is a collection of pre-compiled object code. This option is used only during the linking phase. This option comes at the end of the command line. Multiple libraries are included by using a separate -l option for each library.

The standard system libraries are usually found in /lib and /usr/lib. The names of the libraries take the form of libname.a or libname.so. The part of the library name after the lib and before the suffix is used as the name for linking. For example a common version of the math library is named libm.a. It is linked into a program using the -lm option.

-Ldirectory_name
Use the given directory as a place to search for library files. This directory is used in addition to the standard system library directories. Multiple library directories are specified by using a separate -L option for each directory. There is no space between the -L option and the directory name.

This option is useful only during the linking phase.

Examples

Here are some examples of using g++ with many of the options given above.

For the compilation phase:

      g++ -c -O -Wall -Imy_include_dir myprog.C
    
compiles myprog.C to an object code file with optimization turned on, showing all warnings, and looking in the directory my_include_dir for any additional include files.

For the linking phase:

      g++ -g -Wall -o fun fun.o support.o graphics.o -L/usr/lib/X11 -lX11 -lm
      
links the object code files fun.o support.o and graphics.o into the executable file fun. All warnings are displayed and debugging information is preserved. In addition, the directory /usr/lib/X11 is used to search for additional libraries and the libraries X11 and m (X11 graphics and math) are linked in as well.