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.
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 libraries—and the libraries that depend on them—frequently 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 linker—such as the lib subdirectory of the Visual C++, CodeWarrior, or C++Builder root
directories—programmers 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 <boost/config/auto_link.hpp> void johnpaul(); #endif // JOHNPAUL_HPP_INCLUDED
Here, the line:
#define BOOST_LIB_NAME libjohnpaul
specifies your library name, the line:
#define BOOST_AUTO_LINK_NOMANGLE
indicates that you don’t want to use the Boost name-mangling convention, and the line:
#include <boost/config/auto_link.hpp>
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.