You've written a library that you'd like to distribute as a collection of headers and prebuilt static or dynamic libraries, but you don't want users of your library to have to specify the names of the binaries when they link their applications.
If you are programming for Windows and using the Visual C++, Intel, Metrowerks, Borland, or Digital Mars toolsets, you can use pragma comment in your library's headers to specify the names, and optionally the full file pathnames, of the prebuilt binaries against which any code that includes the headers should be linked.
For example, suppose you want to distribute the library from Example 1-1 as a static library libjohnpaul.lib together with the header johnpaul.hpp. Modify the header as shown in Example 1-26.
Example 1-26. Using pragma comment
#ifndef JOHNPAUL_HPP_INCLUDED #define JOHNPAUL_HPP_INCLUDED #pragma comment(lib, "libjohnpaul") void johnpaul( ); #endif // JOHNPAUL_HPP_INCLUDED
With this change, the Visual C++, Intel, Metrowerks, Borland, and Digital Mars linkers will automatically search for the library libjohnpaul.lib when linking code that includes the header johnpaul.hpp.
In some ways, linking can be a more difficult phase of the build process than compiling. One of the most common problems during linking occurs when the linker finds the wrong version of a library. This is a particular problem on Windows, where runtime librariesand the libraries that depend on themfrequently come in many variants. For this reason, libraries for Windows are often distributed with names mangled to reflect the various build configurations. While this helps to reduce version conflict, it also makes linking harder because you have to specify the correct mangled name to the linker.
For this reason, pragma comment is a very powerful tool. Among other things, it allows you to specify the correct mangled name of a library in a header file, saving the user the trouble of having to understand your name-mangling convention. If, in addition, you design your installation process to copy the binary files to a location automatically searched by the linkersuch as the lib subdirectory of the Visual C++, CodeWarrior, or C++Builder root directoriesprogrammers will be able to use your library simply by including your headers.
So far, so good. There's just one problem: pragma comment is not recognized by all compilers. If you wish to write portable code, you should invoke a pragma only after verifying that it is supported by the toolset being used. For example, you could modify johnpaul.cpp to read:
#ifndef JOHNPAUL_HPP_INCLUDED #define JOHNPAUL_HPP_INCLUDED #if defined(_MSC_VER) || defined(_ _ICL) || defined(_ _MWERKS_ _) && defined(_WIN32) || defined(_ _BORLANDC_ _) defined(_ _DMC_ _) /**/ # pragma comment(lib, "libjohnpaul") #endif void johnpaul( ); #endif // JOHNPAUL_HPP_INCLUDED
This example is already pretty complex, and, unfortunately, it's still not exactly right: some compilers that don't support pragma comment define the macro _MSC_VER for compatibility with Visual C++. Fortunately, Boost provides an easy solution:
#ifndef JOHNPAUL_HPP_INCLUDED #define JOHNPAUL_HPP_INCLUDED #define BOOST_LIB_NAME libjohnpaul #define BOOST_AUTO_LINK_NOMANGLE #include void johnpaul( ); #endif // JOHNPAUL_HPP_INCLUDED
Here, the line:
#define BOOST_LIB_NAME libjohnpaul
specifies your library name, the line:
indicates that you don't want to use the Boost name-mangling convention, and the line:
invokes pragma comment for compilers which support it.