Building a Complex Application from the Command Line

Problem

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

Solution

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

Toolset

Option

All

-I

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

Toolset

Input files

Command line

GCC (Unix)

hellobeatles.olibjohnpaul.alibgeorgeringo.so

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

or

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

Intel (Linux)

 

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

or

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

or

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

GCC (Mac OS X)

hellobeatles.olibjohnpaul.alibgeorgeringo.dylib

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

or

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

or

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

GCC (Cygwin)

hellobeatles.olibjohnpaul.alibgeorgeringo.dll.a

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

or

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

GCC (MinGW)

hellobeatles.olibjohnpaul.alibgeorgeringo.a

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

or

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

Visual C++

hellobeatles.objlibjohnpaul.liblibgeorgeringo.lib

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

Borland

 

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,,

or

link -noi hellobeatles.obj,hellobeatles.exe,NUL,user32.lib kernel32.lib ..johnpaullibjohnpaul.lib ..georgeringolibgeorgeringo.lib,,

Comeau (Windows)

hellobeatles.objlibjohnpaul.liblibgeorgeringo.lib

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 FilesMicrosoft Visual Studio .NET 2003VCin
vcvars32.bat"
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
hellobeatles.cpp
> link -nologo -out:hellobeatles.exe -libpath:../johnpaul 
-libpath:../georgeringo libjohnpaul.lib libgeorgeringo.lib 
hellobeatles.obj

 

Discussion

Searching for included headers

The -I option is used to specify an include path. When a compileractually the preprocessorencounters 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 

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 for this purpose, but Visual C++ and Intel for Windows use -lipath: and Metrowerks uses -search -L. 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 Unixand 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.

See Also

Recipe 1.10, Recipe 1.13, Recipe 1.18, and Recipe 1.23

Building C++ Applications

Code Organization

Numbers

Strings and Text

Dates and Times

Managing Data with Containers

Algorithms

Classes

Exceptions and Safety

Streams and Files

Science and Mathematics

Multithreading

Internationalization

XML

Miscellaneous

Index



C++ Cookbook
Secure Programming Cookbook for C and C++: Recipes for Cryptography, Authentication, Input Validation & More
ISBN: 0596003943
EAN: 2147483647
Year: 2006
Pages: 241

Similar book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net