Learning Boost C++ Libraries

By Arindam Mukherjee
    What do you get with a Packt Subscription?

  • Instant access to this title and 7,500+ eBooks & Videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Free Chapter
    Introducing Boost
About this book

Filled with dozens of working code examples that illustrate the use of over 40 popular Boost libraries, this book takes you on a tour of Boost, helping you to independently build the libraries from source and use them in your own code.

The first half of the book focuses on basic programming interfaces including generic containers and algorithms, strings, resource management, exception safety, and a miscellany of programming utilities that make everyday programming chores easy. Following a short interlude that introduces template metaprogramming and functional programming, the later chapters are devoted to systems programming interfaces, focusing on directory handling, I/O, concurrency, and network programming

Publication date:
July 2015
Publisher
Packt
Pages
558
ISBN
9781783551217

 

Chapter 1. Introducing Boost

Welcome to learning about the richest collection of C++ libraries around, that is, Boost. In this introductory chapter, we will take a look at:

  • The history and evolution of Boost

  • What is Boost?

  • Getting started with Boost libraries

Like all the chapters in the book, this is a hands-on chapter that will require you to type in commands, write and test your code. Therefore, you should have access to a computer with a reasonably modern C++ compiler and an internet connection to download free software, including Boost libraries.

 

How it all started


Sometime around 1997-98, when the draft of the first C++ Standard was being finalized for publication as an ISO/IEC Standard, Robert Klarer from the IBM Labs conceived the idea of a programming language that would be called BOOSE (pronounced "booz"), and which would compete with Java in the area of high-performance embedded software development, which the latter had been aimed at. In a 1998 article for the now defunct C++ Report magazine, C++ guru Herb Sutter wrote a tongue-in-cheek spoof on this new language, whose name ostensibly expanded to Bjarne's Object Oriented Software Environment. In this article, he claimed that portability and potability were, among other things, key advantages of this language, which also supposedly promoted extraordinary camaraderie in team environments and made developers excessively happy, communicative, and passionate.

While this was an April Fools' Day article in 1998, the fact remained that the first C++ Standard was going to have a fairly basic standard library consisting of a memory allocation subsystem, type-generic containers and algorithms, a string class, basic abstractions for input and output devices, and sundry utilities. Now around the same time, a few folks from the C++ Standards Committee formed a group that worked on producing a collection of high-quality, peer-reviewed, free, and open source libraries in C++ that would have wide applicability and complement the features in standard C++. Inspired by BOOSE, perhaps for its stated competition with Java, which was a newer language but with a much richer library, they named this initiative Boost, a working title that stuck (source: FAQ on the Boost website, http://www.boost.org).

 

What is Boost?


Boost is a collection of free, peer-reviewed, portable, open source libraries in C++. Over the last decade and a half, there have been, as of this writing, 57 releases of the Boost libraries. In this span, Boost has released libraries of compelling usefulness that promote correct, portable, efficient, and readable C++ code. A number of prominent Standards Committee members are also the most active participants in Boost and subsequent directions of C++ standardization have been heavily influenced by the work done at Boost. Boost has provided the Standards Committee with the laboratory they need to perfect their ideas for the best new features that C++ should have. Several Boost libraries were included in the Technical Report 1 of the C++ Standards Committee, which considerably enhanced the functionality defined in the C++ 2003 revised standard; these included both language and library features. Most of these libraries made it to the C++11 Standard published in 2011. A couple more library features that originated in Boost have been added to the latest revision of the C++ Standard known as C++14 (published in 2014).

Over the years, Boost has added libraries for string and text processing, including regular expression handling, generic containers compatible with the Standard Library, smart pointers for efficient exception-safe memory management, concurrent programming, network programming, interprocess communication, filesystem handling, template metaprogramming, and many others. The following table lists some of the prominent Boost libraries grouped by category. This is by no means exhaustive:

Category

Libraries

Memory management

Smart Ptr, Align, Pool

Data structures

Container, Array, Multi-Index, Bimap, Pointer Container, Optional, Variant, Any, Tuple, Assign

Algorithms

Algorithm, Range

String and text

Conversion, String Algo, Regex, Tokenizer, Spirit, Xpressive

Systems programming

System, Filesystem, Chrono, Date Time, Thread, Asio, Interprocess

I/O

IOStreams, Locale, Serialization, Format

Higher-order programming

Function, Bind, Phoenix, Signals2

Generic programming

Enable If, Type Traits, MPL, Fusion, Proto

Language features emulation

Foreach, Move, Exception, Parameter

Correctness and testing

Test, Static Assert

Miscellaneous

Utility, Log, Uuid, Program Options, CRC

Boost libraries have found varied use in the industry because of some very high-performance libraries (such as Boost.Asio and Boost.Intrusive), and because of a very permissive and uncomplicated Boost license, which allows source redistribution, distribution of derivative work, and distribution in a binary form for noncommercial as well as commercial purposes with minimal constraints. In the next section, we will set up a development environment that enables us to use any Boost library in our C++ code using consistent conventions. This should serve us well for the rest of the book.

 

Getting started with Boost libraries


We shall now set up a development sandbox for you to write code using the Boost libraries. We can either install a binary distribution of the Boost libraries, or build them from source. If we build them from source, we have a whole range of concerns to take care of from choosing a suitable naming convention for the library files and building the libraries, to making sure that we are linking them to the correct versions of the library. There are platform-specific differences too that need to be handled; we shall take a look at both the Linux and Windows environments.

Necessary software

On Linux, we will only consider the C++ compiler (g++) version 4.8.1 or later, distributed with the GNU Compiler Collection (GCC). On Windows, we will use Visual Studio 2013. You can get more elaborate software support matrices for each Boost release on the Boost website.

Linux toolchain

You should be able to build Boost on most major Linux distributions. I use a Lubuntu 14.04 32-bit installation with GCC 4.8.1 and Clang 3.4. You can possibly build on much older distributions, as the Boost website lists GCC 3.3 as the minimum supported version. If you also want good C++11 support, use GCC 4.8 or higher.

Required software

Minimum version

Recommended version

Ubuntu package

Fedora/CentOS package

GNU C++ compiler

4.8.x

4.8.4

g++

gcc-c++

GNU Standard C++ Library

4.8.x

4.8.4

libstdc++-dev

libstdc++-devel

GNU Standard C++ runtime

4.8.x

4.8.4

libstdc++

libstdc++

If you want to use Clang instead of GCC, the recommended version is 3.4 or higher. Here are the required packages on Ubuntu:

Required software

Minimum version

Recommended version

Ubuntu package

LLVM compiler toolchain

3.2

3.4

llvm

LLVM C, C++, and Objective-C compiler

3.2

3.4

clang

LLVM C++ Standard Library

3.2

3.4

libc++-dev

Windows toolchain

You should be able to build Boost on Visual Studio 7.1 upwards. I use Visual Studio 2013 on a Windows 7 64-bit installation:

Required

software

Minimum version

Recommended version

Visual Studio with Visual C++

7.1

12 (2013)

I would also recommend installing 7-Zip on Windows to extract Boost sources from the .7z or .tar.bz2 archives, which offer much better compression than the .zip archives.

Obtaining and building Boost libraries

You can build the Boost libraries from source or install them as an operating system package on platforms where such as package is available. All examples in this book use Boost version 1.57. You may choose to download a more recent version of the sources and most of the discussion here should still hold. However, few details may change from one release to the next, so you should be prepared to dig into the online documentation.

Planning your Boost sandbox

As part of our day-to-day development work using Boost, we would need access to Boost's header files and Boost's libraries. A vast number of Boost libraries are header-only, which means that you just need to include the appropriate headers and build your sources. Some others have to be built into binary libraries that can be linked statically or dynamically to your application.

If we build from source, we will first identify a directory on our development machine, where we would like to install these files. The choice is arbitrary, but we can follow conventions if they exist. So on Linux, we can choose to install the library headers and binaries under /opt/boost. On Windows, this could be f:\code\libraries\Boost. You are free to choose different paths, just avoid spaces within them for less hassle.

Library naming conventions

Boost library binaries can have names that are difficult to decipher at first. So, we shall learn about what goes into naming the libraries. Library names have different layouts. Depending on the layout, different components are added to the base name in order to identify different facets of the library's binary compatibility and functionality.

Library name components

Each library, whether static or shared, is named according to a well-defined scheme. The name of a library can be split into several components, not all of which are mandatory:

  • Prefix: Libraries may have a prefix, typically lib. On Windows, only static libraries have this prefix while on Unix, all libraries have this prefix.

  • Toolset identifier: Library names may be tagged with the string, identifying the toolset with which it was built. Roughly speaking, a toolset or toolchain is the set of system utilities, including compiler, linker, archiver, and so on, that are used to build libraries and programs. For example, vc120 identifies the Microsoft Visual C++ 12.0 toolchain.

  • Threading model: If a library is thread-safe, that is, it can be used in multithreaded programs without additional synchronization, then its name may be tagged with mt, which stands for multithreaded.

  • ABI: ABI stands for application binary interface. This component captures details, such as whether the library is a debug library (d) or not, whether it is linked to a debug version of the runtime (g) or not, and whether the link to the runtime is static (s) or not. Thus, a debug library that is statically linked to a release version of the runtime would be marked with only sd, while one that is dynamically linked to a debug version would be marked with gd. A release version of the library dynamically linked to a release version of the runtime will have a blank ABI marker.

  • Version: This is the version string of the Boost library. For example, 1_57 would be the version marker for the Boost 1.57 libraries.

  • Extension: Library extensions identify the file types. On Windows, dynamic libraries have the extension .dll, while static libraries and import libraries have the extension .lib. On Linux and some other Unix systems, dynamic libraries have the extension .so, while static libraries or archives have the extension .a. Dynamic library extensions often have a version suffix, for example, .so.1.57.0.

Library name layouts

How a library name is made up of its components determines its name layout. There are three kinds of name layouts supported by Boost: versioned, system, and tagged.

Versioned layout

It is the most elaborate layout and is the default layout on Windows. The general structure of the versioned layout name is libboost_<name>-<toolset>-<threading>-<ABI>-<version>.<ext>. For example, here is the Boost.Filesystem library debug DLL for Windows: boost_filesystem-vc100-mt-gd-1_57.dll. The tokens in the filename tell the complete story. This DLL was built using Visual C++ 10.0 compiler (-vc100), is thread-safe (-mt), and is a debug DLL (d) linked dynamically to the debug version of the runtime (g). The version of Boost is 1.57 (1_57).

System layout

The default layout on Unix is the system layout that removes all the name decorations. The general structure of library names in this layout is libboost_<name>.<ext>. For example, here is the Boost.System shared library on Linux: libboost_filesystem.so.1.57.0. Looking at it, there is no way to tell whether it supports multithreading, whether it is a debug library, or any other detail that you could wean from a filename in the versioned layout. The 1.57.0 suffix of the extension indicates the version of the shared library. This is the Unix convention for versioning shared libraries and is not affected by the Boost name layout.

Tagged layout

There is a third layout called the tagged layout, which is midway between the versioned and system layouts in terms of detail. It removes all the version information but retains other information. Its general structure is libboost_<name>-<threading>-<ABI>.<ext>.

Here is the Boost.Exception static library from Windows built using the non-default tagged layout: libboost_filesystem-mt.lib. This is a static library as indicated by its lib- prefix. Also, -mt indicates that this library is thread-safe, and the lack of an ABI indicator means that this is not a debug library (d), nor does it link to the static runtime (s). Also, it does not link to the debug version of the runtime (g).

The versioned layout is a bit unwieldy. On systems where you need to manually specify names of libraries to link against, moving from one version of Boost to the next would require some effort to fix the build scripts. The system layout is a bit minimalistic and is great for environments where you need only one variant of a given library. However, you cannot have both debug and release versions of the library, or thread-safe and thread-unsafe ones side by side, with system layout. For this reason, in the rest of this book, we will only use tagged layout for the libraries. We will also only build thread-safe libraries (-mt) and shared libraries (.dll or .so). Some libraries can only be built as static libraries and, as such, would be automatically created by the Boost build system. So now, we finally get to the point where we have enough information to start creating our Boost sandbox.

Installing a Boost binary distribution

On Microsoft Windows and several distributions of Linux, you can install a binary distribution of the Boost libraries. The following table lists the methods of installing Boost on some of the popular operating systems:

Operating system

Package name

Install method

Microsoft Windows

boost_1_57_0-msvc-12.0-64.exe (64-bit)

boost_1_57_0-msvc-12.0-32.exe (32-bit)

Download executable from http://sourceforge.net/projects/boost/files/boost-binaries/ and install it by running the executable

Ubuntu

libboost-all-dev

sudo apt-get install libboost-all-dev

Fedora/CentOS

boost-devel

sudo yum install boost-devel

Installing a binary distribution is convenient because it is the fastest way to be up and running.

Installing on Windows

Starting with Boost 1.54, you can download a binary distribution of the Boost libraries, built using Microsoft Visual Studio, from SourceForge. The download is available as a 64-bit or 32-bit installable executable that contains header files, libraries, sources, documentation, and tools. There are separate distributions for different versions of Visual Studio, from version 12 (VS 2013) backward through version 8 (VS 2005). The name of the executable is of the form boost_ver-msvc-vcver-W.exe, where ver is the Boost version (for example, 1_57_0), vcver is the version of Visual C++ (for example, 12.0 for Visual Studio 2013), and W is the native word size of your operating system (for example, 64 or 32).

As part of the installation, you can choose the directory where you want to install the Boost libraries. Let us consider that you choose to install it under boost-dir. Then, the following directories contain the necessary headers and libraries:

Directory

Files

boost-dir

This is the base directory of the Boost installation. All the header files are present in a hierarchy under the boost subdirectory.

boost-dir/libW-msvc-vcver

This directory contains all variants of the Boost libraries, static and shared (DLLs), debug and release. The library filenames follow the versioned layout.

W: 32 or 64 depending on whether you installed a 32-bit version or 64-bit version.

vcver: Visual Studio version.

boost-dir/doc

This directory contains the library documentation in the HTML format and contains scripts to build PDF docs.

Installing on Linux

On Ubuntu, you need to install the libboost-all-dev package. You need to perform the installation using superuser privileges, so run the following command:

$ sudo apt-get install libboost-all-dev

This installs the necessary headers and libraries in the following directories:

Directory

Files

/usr/include

This contains all the header files present in a hierarchy under the boost subdirectory.

/usr/lib/arch-linux-gnu

This contains all the Boost libraries, static and shared (DSOs). The library filenames follow the system layout.

Replace arch with x86_64 for 64-bit operating systems and with i386 for 32-bit operating systems.

On CentOS/Fedora, you need to install the boost-devel package. You need to perform the installation using superuser privileges, so this is the command to run:

$ sudo yum install boost-devel

This installs the necessary headers and libraries in the following directories:

Directory

Files

/usr/include

This contains all the header files present in a hierarchy under the boost directory.

/usr/lib

This contains all the Boost libraries, static and shared (DSOs). The library filenames follow the system layout.

Building and installing the Boost libraries from source

Building the Boost libraries from source offers more flexibility, as it is easy to customize the build, use alternative compilers/toolchains, and change the default name layout like we plan to. We shall build the Boost libraries from a source archive downloaded from the Boost website http://www.boost.org or http://sourceforge.net/projects/boost. I prefer the 7-Zip or the bzip2 archives, as they have the best compression ratios. We will use Boost libraries Version 1.57, and we will look at building them only on Linux and Windows operating systems.

Optional packages

There are several optional packages that are used to provide additional functionality by certain Boost libraries when present. These include:

  • The zlib and bzip2 development libraries, used by Boost.IOStream to read and write compressed archives in gzip and bzip2 formats

  • The ICU i18n development libraries, which are heavily used by Boost.Locale and also by Boost.Regex to support Unicode regular expressions

  • The expat XML parser library, used by the Boost.Graph library to support the GraphML XML vocabulary for describing graphs

Some of these libraries may be made available through your native package management systems, particularly on Linux. When installed from such packages, the Boost build system may find these libraries automatically and link them by default. If you chose to build these libraries from source and installed them at non-standard locations instead, then you should use specific environment variables to point to the installation directory of these libraries or to the include and library directories. The following table summarizes these optional libraries, their source websites, Ubuntu package names, and the environment variables needed by Boost to identify them when installed from source:

Library

Details

Zlib library (http://www.zlib.net)

Environment variable: ZLIB_SOURCE (extracted source directory)

Ubuntu packages: zlib1g, zlib1g-dev, and zlib1c

Bzip2 library (http://www.bzip.org/downloads.html)

Environment variable: BZIP2_SOURCE (extracted source directory)

Ubuntu packages: libbz2 and libbz2-dev

ICU library (http://www.icu-project.org/download)

Environment variables:

HAVE_ICU=1

ICU_PATH (installation root)

Ubuntu package: libicu-dev

Expat library (http://sourceforge.net/projects/expat)

Environment variables: EXPAT_INCLUDE (expat include dir) and EXPAT_LIBPATH (expat library dir)

Ubuntu packages: libexpat1 and libexpat1-dev

We will be using the gzip and bzip2 libraries in Chapter 9, Files, Directories, and IOStreams, to compress data, while we will not be using the ICU and Expat libraries for the code examples in this book.

Building the Boost libraries on Linux

If you choose not to install a binary distribution of Boost or if such a distribution is not available for your platform, then you must build the Boost libraries from source. Download the source archives for the Boost libraries, zlib and bzip2. Assuming that you want to install Boost in the/opt/boost directory, perform the following steps from a shell command prompt to build Boost with the GNU toolchain:

  1. Create a directory and extract the Boost source archive in it:

    $ mkdir boost-src
    $ cd boost-src
    $ tar xfj /path/to/archive/boost_1_57_0.tar.bz2
    $ cd boost_1_57_0
    
  2. Generate the Boost build system for your toolset. The following should work if you are building with g++:

    $ ./bootstrap.sh
    

    If you are using Clang instead, run the following:

    $ ./bootstrap.sh toolset=clang cxxflags="-stdlib=libc++ -std=c++11" linkflags="-stdlib=libc++"
    
  3. Extract the bzip2 and zlib source archives and make a note of the directories they have been extracted to.

  4. Build the libraries and install them. For GCC, run the following command:

    $ ./b2 install --prefix=/opt/boost --build-dir=../boost-build --layout=tagged variant=debug,release link=shared runtime-link=shared threading=multi cxxflags="-std=c++11" -sZLIB_SOURCE=<zlib-source-dir> -sBZIP2_SOURCE=<bzip2-source-dir>
    

    For Clang, run the following command instead:

    $ ./b2 install toolset=clang --prefix=/opt/boost --build-dir=../boost-build --layout=tagged variant=debug,release link=shared runtime-link=shared threading=multi cxxflags="-stdlib=libc++ -std=c++11" linkflags="-stdlib=libc++" -sZLIB_SOURCE=<zlib-source-dir> -sBZIP2_SOURCE=<bzip2-source-dir>
    

The last step should build all the Boost libraries and install them under the /opt/boost directory, as identified by the --prefix option. All the libraries will be installed under /opt/boost/lib and all include files under /opt/boost/include. In addition to the Boost libraries, you should also see libboost_zlib-mt.so and libboost_bzip2-mt.so—the dynamic shared objects for zlib and bzip2, which libboost_iostreams-mt.so depends on.

  • The --build-dir option would identify the directory in which the intermediate products of the build are created.

  • The --layout=tagged option chooses the tagged layout for library names.

  • We will build only thread-safe (threading=multi) shared libraries (link=shared) if possible, linked them to the dynamic runtime (runtime-link=shared). We would need both debug and release versions of the library (variant=debug,release).

  • The -sZLIB_SOURCE=<zlib-source-dir> option is used to point the build to the directory under which the zlib sources were extracted in step 3; likewise, for the bzip2 source directory, using -sBZIP2_SOURCE=<bzip2-source-dir>.

  • If you want to build Boost libraries using support for C++11, then you should use the cxxflags="-std=c++11" option. Throughout the rest of the book, many of the code examples use features from C++11. Enabling a C++11 build of Boost at this point might be a good idea. Make sure that your compiler has good support for C++11. For g++, it would be version 4.8.1 or later. Also, make sure that you compile all your own code using the Boost libraries with C++11 as well.

Note

Most of the examples in this book use C++11 features, and so you should keep the C++11 option on while compiling Boost. Appendix provides a short introduction to the important C++11 features used in this book, and also describes how you can emulate them in C++03 using Boost if you are still using an older compiler.

Building the Boost libraries on Windows

Once you have downloaded the Boost source archive, from a Windows Explorer session, create a directory called boost-src and extract the source archive inside this directory. Assuming that you want to install Boost in the boost-dir directory and boost-build is the directory in which the intermediate products of the build are kept, perform the following steps from a command prompt:

  1. Initialize the 32-bit Visual C++ build environment to build the Boost build system (even if you want to build 64-bit):

    "C:\Program Files\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
    
  2. On a 64-bit system with a 32-bit Visual Studio installation, Visual Studio is typically installed under C:\Program Files (x86), so you will have to run this command instead:

    "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86
    
  3. Generate the Boost build system for your toolset:

    cd /d drive:\path\to\boost-src
    bootstrap.bat
    
  4. If you want to build 64-bit Boost libraries, initialize the 64-bit Visual C++ build environment:

    "C:\Program Files\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
    
  5. On a 64-bit system with 32-bit Visual Studio installation, you will have to run this command instead:

    "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
    
  6. Extract the bzip2 and zlib source archives, and make a note of the directories they have been extracted to.

  7. Build the libraries and install them. If you want to build 32-bit libraries, use the following command line:

    b2 install --libdir=boost-dir\libs --includedir= boost-dir\include --build-dir= boost-build --layout=tagged variant=debug,release threading=multi link=shared runtime-link=shared -sZLIB_SOURCE=<zlib-src-dir> -sBZIP2_SOURCE=<bzip2-src-dir>
    
  8. If you want to build 64-bit libraries, use the following command line:

    b2 install --libdir=boost-dir\libs64 --includedir= boost-dir\include --build-dir= boost-build64 --layout=tagged variant=debug,release threading=multi link=shared runtime-link=shared address-model=64 –sZLIB_SOURCE=<zlib-src-dir> -sBZIP2_SOURCE=<bzip2-src-dir>
    

This last step builds and installs the necessary headers and libraries in the following directories:

Directory

Files

boost-dir/include

All header files present in a hierarchy under the boost directory.

boost-dir/libs

All 32-bit Boost libraries, static and shared libraries (DLLs), debug and release.

boost-dir/libs64

All 64-bit Boost libraries, static and shared libraries (DLLs), debug and release

In addition to the Boost libraries, you should also see boost_zlib-mt.dll and boost_bzip2-mt.dll—the DLLs for zlib and bzip2, which boost_iostreams-mt.dll depends on.

Let us take a look at the various options we have used in the preceding commands:

  • The --build-dir option will identify the directory in which the intermediate products of the build are created.

  • The --layout=tagged option chooses the tagged layout for the library names, as explained earlier.

  • We will build only the shared libraries (link=shared). If possible, link them to the dynamic runtime (runtime-link=shared), and create thread-safe libraries (threading=multi).

  • We will want both debug and release versions of the library (variant=debug,release).

  • The 32- and 64-bit builds will take place in separate intermediate directories identified by the --build-dir option and will be copied to separate library directories identified by the --libdir option.

  • The address-model=64 option would trigger the 64-bit build.

Under Visual Studio 2013, C++11 support is automatically enabled, and you do not need to use any specific switches for the purpose.

Using Boost libraries in your projects

We shall now write our first small C++ program that uses the Boost Filesystem library to check for the existence of a file whose name is passed to on the command line and then build on Linux and Windows.

Here is the listing for chkfile.cpp:

 1 #include <iostream>
 2 #include <boost/filesystem.hpp>
 3 // define a short alias for the namespace
 4 namespace boostfs = boost::filesystem;
 5
 6 int main(int argc, char *argv[])
 7 {
 8   if (argc <= 1) {
 9     std::cerr << "Usage: " << argv[0] << " <filename>"
10               << std::endl;
11     return 1;
12   }
13
14   boostfs::path p(argv[1]);
15
16   if (boostfs::exists(p)) {17     std::cout << "File " << p << " exists." << std::endl;
18   } else {
19     std::cout << "File " << p << " does not exist." << '\n';
20   }
21
22   return 0;
23 }

Linking against Boost libraries on Linux

If you have installed Boost in a nonstandard location (which is typically the case if you have not installed it from a native package), then you will need to make sure that your preprocessor can find the Boost header files you have included using the –I option in the compiler:

$ g++ -c chkfile.cpp -I/opt/boost/include -std=c++11

This step will create an object file called chkfile.o, which we will link to the binary. You can specify which library to link to using the -l option. In case of a nonstandard installation, you will need to ensure that the linker can find the path to the library you want to link against using the -L option:

$ g++ chkfile.o -o chkfile -L/opt/boost/lib -lboost_filesystem-mt -lboost_system-mt -std=c++11

Note

Use the -std=c++11 option only if you built your Boost libraries using C++11.

The preceding command line will work for either a static or a shared library. However, if both types of library are found, it will use the shared version. You can override this with appropriate linker options:

$ g++ chkfile.o -o chkfile -L/opt/boost/lib -Wl,-Bstatic -lboost_filesystem-mt -Wl,-Bdynamic -lboost_system-mt -std=c++11

In the preceding case, the filesystem library is linked statically while others are linked dynamically. The -Wl switch is used to pass its arguments to the linker. In this case, it passes the -Bstatic and -Bdynamic switches.

If it is a shared library that you link against, then at runtime the dynamic linker needs to locate the shared library and load it too. The way to ensure this varies from one version of Unix to the other. One way to ensure this is to embed a search path in your executable using the rpath linker directive:

$ g++ -o chkfile chkfile.o -L/opt/boost/lib -lboost_filesystem-mt -lboost_system-mt -Wl,-rpath,/opt/boost/lib:/usr/lib/boost -std=c++11

On the target system, where the binary mytest is run, the dynamic linker would look for the filesystem and system shared libraries under /opt/boost/lib and /usr/lib/boost.

Other ways besides using the rpath mechanism also exist. Linux uses a utility called ldconfig to locate shared libraries and update search paths. For more details, look at the man pages for ldconfig (8). On Solaris, the crle utility performs a similar action.

Linking against Boost libraries on Windows

Using the Visual Studio IDE, we will have to tweak certain project settings in order to link against the Boost libraries.

First, ensure that your compiler is able to find the necessary header files:

  1. Open your C++ project in Visual Studio. From the menu, select Project | Project Properties.

  2. In the Property Pages dialog that comes up, expand Configuration Properties and select C/C++.

  3. Edit the value of Additional Include Directories by adding the path to your Boost, include directories. Separate it from other entries in the field using a semicolon:

  4. Next, ensure that your linker is able to find the shared or static libraries. In the Project Properties dialog, under Configuration Properties, choose Linker.

  5. Edit the Additional Library Directories field to add the path to the Boost libraries, separated by a semicolon from any other entries:

  6. Now you can leverage Boost's auto-linking feature on Windows to automatically link to the correct libraries. To enable this, you have to define the BOOST_ALL_DYN_LINK preprocessor symbol. To do this, in the Project Properties dialog, navigate to Configuration Properties | C/C++ | Preprocessor, and add BOOST_ALL_DYN_LINK to the Preprocessor Definitions field, separating it from other entries with a semicolon.

If you built your Boost libraries on Windows with the default layout (versioned), this is all you will need to do for linking correctly. If we use the tagged layout, we must also define a second preprocessor symbol BOOST_AUTO_LINK_TAGGED. If we use system layout for naming, we will need to define BOOST_AUTO_LINK_NOMANGLE instead. You will get a linker error without these definitions:

You should now be able to build your project from your IDE without any problems. In order to run your program, the dynamic linker must be able to locate the dynamic library. To take care of this, on Windows, you can add the path of your Boost libraries to the PATH environment variable. For running your programs from within the IDE, you can add the path of your Boost libraries to the PATH variable by navigating to Debugging | Environment, as shown in the following screenshot:

Building the code listings in this book

Each chapter in this book includes the example source code, which is also available for download from the Packt website (http://www.packtpub.com). You should download and build these examples on your development machines.

CMake

In order to build the examples, you need to install CMake, which is one of the most popular cross-platform build tools for C++ programs. With CMake, you can easily generate a build system of your choice on an operating system of your choice, using a single set of CMake specifications.

You can download a binary package for CMake from www.cmake.org, or download a source archive and build it on a platform of your choice.

Note

Minimum version required: CMake 2.8.

Windows: A 32-bit exe-installer is available for Windows that works for both 32-bit and 64-bit builds.

Linux: CMake is usually bundled with all major Linux distributions and is available as an optional package. Consult your distribution's package repository.

Code examples

Download the source code archive and extract it to a directory on your development machine. The layout of the extracted directory would look like this:

The source code archive available for download contains separate directories for each chapter. Within each chapter directory, you will find the complete source code for each example. The source code files are named based on the listing identifier.

A listing identifier is a unique tag used for examples in this book, as shown in the following screenshot:

Here, the listing identifier is Listing 11.18 and indicates that this is the eighteenth example in Chapter 11, Network Programming Using Boost Asio. Therefore, in the ch11 folder, you will find listing11_18.cpp, which contains the asynchronous UDP server example that appears in Chapter 11, Network Programming Using Boost Asio. In some cases, a big example is broken down into multiple listings in the text, but they all form part of the same source file. In such cases the listings are tagged with letters; for example, listing 7.22a, 7.22b, 7.22c, and so on. You can still expect a file called listing7_22.cpp, which combines the code from these listings.

In order to build all the examples in this book, you need to follow these steps:

  1. Make sure that CMake 2.8 or higher is installed.

  2. Extract the source archive for the book to a directory, say srcdir.

  3. Change to the cmake_bin directory under the source directory:

    $ cd srcdir/lbcpp-src/cmake_bin
    
  4. Export the BOOST_DIR environment variable to point to the Boost installation directory.

    For example, if it is /opt/boost on Linux, you can run the following command:

    $ export BOOST_DIR=/opt/boost
    

    If you have installed Boost from a standard package in the package repository of your distribution, then you can skip this step.

    On Windows, if you have installed it under f:\boost, you can run this command:

    set BOOST_DIR=f:\boost
    
  5. If the Boost include directory and the Boost library directory do not share a common parent, as may be the case if you installed a binary distribution of Boost, then you should skip setting BOOST_DIR and instead set the following two environment variables:

    • BOOST_INCDIR should be set to the directory that contains the Boost header files, for example, /usr/include on Ubuntu.

    • BOOST_LIBDIR should be set to the directory that contains the Boost library files, for example, /usr/lib/x86_64-linux-gnu on Ubuntu.

  6. Generate the build system of your choice using CMake.

    On Linux, run the following command:

    $ cmake
    

    This generates a Makefile-based build system using GNU g++. If you want to use clang++ instead, export the environment variables CC and CXX, as shown here:

    export CC=`which clang`
    export CXX=`which clang++`

    On Windows, run the following command:

    $ cmake .. -G "Visual Studio 12"
    

    This generates a Visual C++ 2013 solution file and project files. The string passed with the -G option is called the generator string and identifies the toolchain for which you want to generate the build system. The CMake documentation lists all the supported generator strings. For our purposes, we will use Visual Studio 12 or Visual Studio 12 Win64.

  7. Build the sources using the generated build system.

    On Linux, you can build it by simply running the following command:

    $ gmake
    

    On Windows, it is best to build by opening the generated solution file in Visual C++ IDE and then building all the sources or a single source at a time. You can run the examples by running the executables formed under srcdir/lbcpp-src/bin.

We do not cover CMake in this book. It is worth exploring CMake further on your own, and a great place to get started is the CMake Wiki (http://www.cmake.org/Wiki/CMake).

 

Self-test questions


  1. What are the different types of name layouts supported by Boost libraries?

    a. Tagged, native, and mangled

    b. Tagged, mangled, and versioned

    c. Tagged, versioned, and system

    d. Versioned, systems, and decorated

  2. Boost allows you to automatically link to necessary Boost libraries on Windows.

    a. True

    b. False

  3. What does the following filename tell you about the library?

    boost_date_time-vc100-mt-gd-1_57.dll

    Tick all that apply.

    a. It is the DateTime library.

    b. It is a thread-safe library.

    c. It was built using g++.

    d. It is not a debug library.

  4. What is the name layout of the following library?

    libboost_exception-mt-gd.lib

    a. Tagged

    b. System

    c. Versioned

    d. Default

 

Summary


In this chapter, we got an overview of the Boost C++ libraries and set up a development environment for us, which should help us to easily build and run C++ programs, using Boost libraries that we will learn in the rest of the book.

In the next chapter, we will learn a variety of techniques using different Boost libraries, which simplify some common day-to-day programming tasks and set us up for the heavy lifting to be done in the later chapters.

About the Author
  • Arindam Mukherjee

    Arindam Mukherjee is a senior principal software engineer at Symantec, Pune, India, where he is involved in the research and development of business continuity solutions for enterprises. He has used C++ extensively for developing large-scale distributed systems. He was a speaker at Dr. Dobb's Journal India Conference 2014 and is the organizer of regular meets for the Pune C++ and Boost Meetup. He believes that writing books and articles, speaking for interest groups, and engaging with the programming community are the best ways to develop a critical understanding of technology. He is also an amateur musician, dabbles in food photography, and loves profound discussions with his 4-year-old daughter, especially about dinosaurs and their diets.

    Browse publications by this author
Latest Reviews (7 reviews total)
Very informative overview about boost lib. Missing more info about range.asaptors.
Buen contenido a precio ajustado
Good overview of many useful Boost concepts.
Learning Boost C++ Libraries
Unlock this book and the full library FREE for 7 days
Start now