1.23. Specifying a Runtime Library Variant

Problem

Your toolset comes with several variants of its runtime support libraries and you want to instruct your compiler and linker which variant to use.

Solution

Runtime libraries supplied with a given toolset can vary depending on whether they are single- or multithreaded, whether they are static or dynamic, and whether or not they were built with debugging information.

If you are using Boost.Build, these three choices can be specified using the threading, runtime-link, and variant features, described in Table 1-15. For example, to specify a statically linked runtime library, add <runtime-link>static to your target’s requirements, or use the command-line option runtime-link=static. To specify a multithreaded runtime library, add <threading>multi to your target’s requirements, or use the command-line option threading=multi.

If you are building from the command line, use the compiler and linker options presented in Tables 1-30 through 1-36. The command-line options and library names for debug and release configurations as generally quite similar; in the following tables, the letters in brackets should be supplied only for debug configurations. The names of the dynamic variants of the runtime libraries are provided in parentheses; these libraries must be available at runtime if dynamic linking is selected.

Table 1-30. Compiler options for runtime library selection using Visual C++ or Intel (Windows)

Static linking

Dynamic linking

Single-threaded

-ML[d] [15]

n/a

Multithreaded

-MT[d]

-MD[d]( msvcrt[d].dll, msvcr80[d].dll)[16]

[15] Beginning with Visual Studio 2005, currently in beta, the options -ML and -MLd have been deprecated, and single-threaded, statically linked runtime libraries are no longer distributed.

[16] Previous versions of Visual C++ used the DLL’s msvcr71.dll, msvcr71d.dll, msvcr70.dll, msvcr70d.dll, etc.

Table 1-31. Compiler options for runtime library selection using Metrowerks (Windows)

Static linking

Dynamic linking

Single-threaded

-runtime ss[d]

n/a

Multithreaded

-runtime sm[d]

-runtime dm[d](MSL_All-DLL90_x86[_D].dll)

Table 1-32. Command-line options for runtime library selection using CodeWarrior 10 for Max OS X

Static linking

Dynamic linking

No options necessary

Consult the Metrowerks documentation for command-line options (MSL_All_Mach-O[_D].dylib).

Table 1-33. Compiler and linker options for runtime library selection using Borland

Static linking

Dynamic linking

Single-threaded

-WM

-WM- -WR -WC[17] (cc3260.dll)

Multithreaded

-WM

-WM -WR -WCa (cc3260mt.dll)

[17] The option -WC is required only when building a console application.

Table 1-34. Compiler options for runtime library selection using Digital Mars (all runtime libraries are multithreaded)

Static linking

Dynamic linking

No options necessary

-ND -D_STLP_USE_DYNAMIC_LIB(sccrt70.dll, stlp45dm.dll)

Table 1-35. Linker options for runtime library selection using GCC

Static linking

Dynamic linking

-static [18]

No options necessary

[18] This option disables all dynamic linking, not just dynamic linking with runtime support libraries.

For example, to specify a dynamically linked release build of the Visual C++ runtime library, use the compiler option -MD. To specify a statically linked, single-threaded debug build of the Metrowerks runtime library on Windows, use the compiler option -runtime ssd. To specify a single-threaded, dynamically linked build of the Borland runtime library, pass the options -WM- -WR -WC to the compiler and to the linker.

Instructions for specifying a runtime library variant from your IDE are presented in Table 1-36.

Table 1-36. Specifying a runtime library variant from your IDE

IDE

Configuration

Visual C++

From your project’s property pages, go to Configuration Properties C/C++ Code Generation and use the drop-down list labeled Runtime Library.

CodeWarrior

For dynamic library projects, add the object file /usr/lib/dylib1.o and the libraries MSL_Shared_AppAndDylib_Runtime[_D].lib and MSL_All_Mach-O[_D].dylib to your project, and remove any libraries of the form MSL_<XXX>_Mach-O[_D].lib.

For executable projects, add the object file /usr/lib/crt1.o and the libraries MSL_Shared_AppAndDylib_Runtime[_D].lib and MSL_All_Mach-O[_D].dylib to your project, and remove any libraries of the form MSL_<XXX>_Mach-O[_D].lib.

C++Builder

Whether a project will be single- or multithreaded must be specified when you create it. To select a static or dynamic runtime library, go to Linker from Project Options and check or uncheck Use dynamic RTL.

Dev-C++

To select a statically linked runtime library, specify the command-line option -static, as described in Recipe 1.20.

Discussion

A runtime library contains implementations of utility functions required by a program while it is running. Runtime libraries generally contain implementations of functions from the C standard library, platform specific functions for accessing operating system services such as threads and file systems, and functions that provide the infrastructure for C++ language features such as runtime type information (RTTI) and exception handling.

In most cases, the more choices you have, the better; the proliferation of runtime library variants, however, presents some problems. The main challenge is ensuring that all the components of an application—static libraries, dynamic libraries, and executables—use a single variant of the runtime library. If not, the application may fail to link, or hard-to-diagnose runtime failures may occur.

Tip

When using third-party libraries, you sometimes have no control over which variants of the runtime libraries are linked against. In such cases, you may be forced to use several runtime library variants in a single application.

So how should you decide which runtime library to use? Two of the choices—single- versus multi-threaded and debug versus release—are fairly straightforward.

If your project uses multiple threads, or depends on libraries which are multithreaded, you must select a multithreaded variant of the runtime library if your toolset provides one. Calling runtime library functions from multiple threads if the runtime library was not built with thread support can lead to unpredictable runtime behavior. Similarly, if you are producing a debug build, you should use a debug variant of the runtime library, if available.

The last choice—whether to use a static or dynamic runtime library—is more difficult. Using a statically linked runtime has several advantages. First, it can make the overall size of your distribution smaller—if you would otherwise have to distribute a dynamic runtime—since only those functions that your application uses will be linked in. (If you know that the dynamic runtime is already available on your target system, however, linking to the static runtime will probably make your distribution larger.) Second, by linking with the static runtime, you avoid versioning problems that can occur when several different versions of a dynamic library exist on a single system.

Linking with a dynamic runtime library is also attractive, however. This is because a very effective way to organize an application is as a collection of dynamic libraries. For one thing, it allows parts of the application to be updated without requiring the entire application to be reinstalled. Furthermore, applications can sometimes improve their performance significantly by taking advantage of the delay-loading feature of DLLs on Windows. But because all components of an application should use a single variant of the runtime library, once an application makes use of a single dynamic library, all the component of that application should use dynamically linked runtimes. As a result, using a dynamically linked runtime makes your application easier to modularize.

I recommend that you choose dynamic linking most of the time. As mentioned earlier, however, sometimes static linking is more appropriate. Sometimes, it’s impossible to know in advance what type of linking is appropriate, because you don’t know how a library you’ve written will be used. In that case, a common solution is to provide multiple variants of your library, linked against different variants of the runtime libraries.

Get C++ Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.