O'Reilly logo

C++ Cookbook by Jeff Cogswell, Jonathan Turkanis, Christopher Diggins, D. Ryan Stephens

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

1.5. Building a Complex Application from the Command Line


You wish to use your command-line tools to build an executable that depends on several static and dynamic libraries.


Start by building the static and dynamic libraries on which your application depends. Follow the instructions distributed with the libraries, if they are from a third party; otherwise, build them as described in Recipe 1.3 and Recipe 1.4.

Next, compile your application's .cpp files into object files as described in "Building a Simple "Hello, World" Program from the Command Line. You may need to use the -I option to tell your compiler where to search for the headers needed by your application, as shown in Table 1-12.

Table 1-12. Specifying directories to search for headers





Finally, use your linker to produce an executable from the collection of object files and libraries. For each library, you must either provide a full pathname or tell the linker where to search for it.

At each stage of this process, if you are using a toolset which comes with static and dynamic variants of its runtime libraries, and if your program uses at least one dynamic library, you should direct the compiler or linker to use a dynamically linked runtime library, as described in Recipe 1.23.

Table 1-13 presents commands for linking the application hellobeatles from Example 1-3. It assumes that:

  • The current directory is hellobeatles.

  • The static library libjohnpaul.lib or libjohnpaul.a was created in the directory johnpaul.

  • The dynamic library georgeringo.dll, georgeringo.so, or georgeringo.dylib and its import library, if any, were created in the directory georgeringo.


Since Comeau can't build dynamic libraries, as mentioned in Recipe 1.4, the entry for Comeau in Table 1-13 assumes that libgeorgeringo has been built as a static library rather than as a dynamic library. To build libgeorgeringo as a static library, remove the modifier GEORGERINGO_DECL from the declaration of the function georgeringo() in Example 1-2.

Table 1-13. Commands for linking the application hellobeatle.exe


Input files

Command line

GCC (Unix)


g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo


g++ -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a../georgeringo/libgeorgeringo.so

Intel (Linux)

icpc -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo


icpc -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a../georgeringo/libgeorgeringo.so

Comeau (Unix)

como —no_prelink_verbose -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo


como —no_prelink_verbose -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a ../georgeringo/libgeorgeringo.a

GCC (Mac OS X)


g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo


g++ -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a../georgeringo/libgeorgeringo.dylib

Metrowerks (Mac OS X)

mwld -o hellobeatles hellobeatles.o -search -L../johnpaul -search -L../georgeringo -ljohnpaul -lgeorgeringo


mwld -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a ../georgeringo/libgeorgering.dylib

GCC (Cygwin)


g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo


g++ -o hellobeatles hellobeatles.o ../johnpaul/libjohnpaul.a../georgeringo/libgeorgeringo.dll.a



g++ -o hellobeatles hellobeatles.o -L../johnpaul -L../georgeringo -ljohnpaul -lgeorgeringo


g++ —o hellobeatles hellobeatles.o../johnpaul/libjohnpaul.a../georgeringo/libgeorgeringo.a

Visual C++


link -nologo -out:hellobeatles.exe -libpath:../johnpaul -libpath:../georgeringo libjohnpaul.lib libgeorgeringo.lib hellobeatles.obj

Intel (Windows)

xilink -nologo -out:hellobeatles-libpath:../johnpaul -libpath:../georgeringo libjohnpaul.lib libgeorgeringo.lib hellobeatles.obj

Metrowerks (Windows)

mwld-o hellobeatles-search -L../johnpaul libjohnpaul.lib -search -L../georgeringo libgeorgeringo.lib hellobeatles.obj

Metrowerks (Mac OS X)[6]

mwld -o hellobeatles hellobeatles.o -search -L../johnpaul -search -L../georgeringo libjohnpaul.a libgeorgeringo.dylib

CodeWarrior 10.0 (Mac OS X)[7]

Consult the Metrowerks documentation


bcc32 -q -WR -WC -ehellobeatles -L.../johnpaul -L.../georgeringolibjohnpaul.lib libgeorgeringo.lib hellobeatles.obj

Digital Mars

link -noi hellobeatles.obj,hellobeatles.exe,NUL,user32.lib kernel32.lib ..\johnpaul\ ..\georgeringo\ libjohnpaul.lib libgeorgeringo.lib,,


link -noi hellobeatles.obj,hellobeatles.exe,NUL,user32.lib kernel32.lib ..\johnpaul\libjohnpaul.lib ..\georgeringo\libgeorgeringo.lib,,

Comeau (Windows)


como —no_prelink_verbose -o hellobeatles ../johnpaul/ libjohnpaul.lib ../georgeringo/libgeorgeringo.lib hellobeatles.obj

[6] hellobeatles may not execute properly when built with the indicated command line, since the application will make use of two copies of Metrowerks's static runtime support libraries. (See Recipe 1.23.)

[7] CodeWarrior 10.0 for Mac OS X will provide dynamic variants of its runtime support libraries; these should be used when building hellobeatles. (See Recipe 1.23.)

For example, if you use Microsoft Visual Studio .NET 2003, and if it is installed in the standard location on the C drive, you can build hellobeatles.exe from the command line by changing to the directory hellobeatles and entering the following from the commands:

> "C:Program Files\Microsoft Visual Studio .NET 2003\VC\bin\
Setting environment for using Microsoft Visual Studio 2005 tools.
(If you have another version of Visual Studio or Visual C++ installed 
and wish to use its tools from the command line, run vsvars32.bat for 
that version.)
> cl -c -nologo -EHsc -GR -Zc:forScope -Zc:wchar_t -MD -I.. 
-Fohellobeatles hellobeatles.cpp
> link -nologo -out:hellobeatles.exe -libpath:../johnpaul 
-libpath:../georgeringo libjohnpaul.lib libgeorgeringo.lib 


Searching for included headers

The -I option is used to specify an include path. When a compiler—actually the preprocessor—encounters an include directive of the form:

#include "file"

it typically first attempts to find the referenced file by interpreting the given pathname relative to the location of the source file being processed. If this is unsuccessful, it attempts to locate the file in one of the directories specified with the -I option, and then in a list of toolset-dependent directories, which can often be configured using environment variables.

The situation is similar when an included header is specified using angle brackets, like so:

#include <file>

except that compilers generally don't interpret the given pathname relative to the location of the source file being processed.

Passing libraries to the linker

There are several interesting aspects of the command lines in Table 1-13.

On Windows, the input to the linker consists of object files, static libraries, and import libraries; on Unix, it consists of object files, static libraries, and dynamic libraries.

On both Windows and Unix, libraries can be passed to the linker in two ways:

  • By specifying a pathname on the command line

  • By specifying the simple name of the library together with a location to search for the library

Table 1-13 illustrates both methods.

The locations to search for libraries can usually be specified on the command line. Most linkers use the option -L<directory> for this purpose, but Visual C++ and Intel for Windows use -lipath: <directory> and Metrowerks uses -search -L<directory>. The Digital Mars linker allows library search paths to be listed on the command line alongside library files, with search paths distinguished from library files by a trailing backslash; it also requires that backslashes be used as pathname separators.


Comeau does not provide an option for specifying a library search path on Windows.

In addition to the locations explicitly specified, linkers usually search a list of toolset-dependent directories, which can often be configured using environment variables. On Windows, the list of directories typically includes the lib subdirectory of the toolset installation. As a result, if you copy .lib files to this directory, you can specify them by name on the command line without specifying a search location. If you combine this method with the technique described in Recipe 1.25, you can avoid passing the linker any information about a library.

The way the name of a library is specified to the linker differs between Unix and Windows. On Windows, the full name of the library is specified, including the file extension. On Unix—and on Windows when using the GCC toolset — libraries are specified using the -l option followed by the name of the library, with the file extension and the lib prefix removed. This means that the name of a library must begin with lib to be automatically found by the linker. More interestingly, it gives the linker the opportunity to choose between several versions of a library. If the linker finds both static and dynamic version of a library, the dynamic library is selected, unless otherwise specified. On some systems, the linker may choose between several versions of a dynamic library based on the portion of the file name following .so.


Metrowerks supports both the Windows and the Unix styles for specifying library names.

Finally, be aware that Unix linkers can be very sensitive to the order in which object files and static libraries are specified on the command line: if a static library or object file references a symbol defined in a second static library or object file, the first file must appear before the second file on the command line. To resolve circular dependencies, it is sometimes necessary to specify a given library or object file more than once. Another solution is to pass a sequence of object files and static libraries to linker bracketed by -( and -); this causes the file to be searched repeatedly until all references are resolved. This option should be avoided if possible because it can significantly degrade performance.

Running your application

If your application uses a dynamic variant of your toolset's runtime library, the runtime library must be available when your application is run and in a location where it will be found automatically by the operating system's dynamic loader. Typically, this means that the dynamic runtime library must be placed either in the same directory as your application or in one of a list of system-specific directories. This is more of a concern when developing for Windows than when developing for Unix, since on Unix the appropriate runtime libraries are often already installed in the correct locations. The names of the dynamic runtime libraries distributed with the various toolsets are given in Recipe 1.23.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required