| Home | Libraries | People | FAQ | More

## Boostdep

Copyright © 2014-2016 Peter Dimov

Distributed under the Boost Software License, Version 1.0.

## Introduction

Boostdep is a tool for generating Boost dependency reports. It scans the header or source files of the Boost libraries for `#include` directives, builds a dependency graph from this information and outputs its findings in plain text or HTML.

### Modular Boost

Boostdep requires the so-called "modular Boost" directory structure.

If you already have a modular Boost installation, you can skip this section. Otherwise, read on.

Boost libraries reside in subdirectories under the `libs` directory. For example, the contents of the Boost.Filesystem library are in `libs/filesystem`. This includes the build scripts (in `libs/filesystem/build`), the source files (in `libs/filesystem/src`), the tests (in `libs/filesystem/test`), the documentation (in `libs/filesystem/doc`), and so on.

In the past, when Boost used SVN as its version control system, the header files were an exception. The header files of all libraries resided in the `boost` subdirectory, and it wasn't possible to accurately determine which header belonged to which library.

When Boost moved to Git for version control, header files were moved to their corresponding libraries, into an `include` subdirectory. The header files of Boost.Filesystem are now in `libs/filesystem/include`.

For compatibility, `boost` is now a "virtual" directory, containing links to the headers. It's maintained automatically by Boost.Build. (The command `b2 headers` creates or recreates the contents of the `boost` directory.)

This new structure allows Boostdep to determine that, when faced with an `#include <boost/filesystem.hpp>` directive, that this header is part of Boost.Filesystem, and that therefore, the current library being scanned depends on Boost.Filesystem.

Unfortunately, Boost releases do not have this structure. For backward compatibility, they have an old-style `boost` directory containing all header files, whereas the per-library `include` subdirectories are missing. Therefore, Boostdep will not work with a downloaded Boost release.

To use Boostdep, you will have to clone the Boost Git repository instead. To do that, execute the following command:

    git clone https://github.com/boostorg/boost.git boost

This will download the Boost "superproject" (the master project, without any libraries) and place it into the subdirectory `boost` of the current directory. To override the directory name, pass it as a second argument instead of `boost`:

    git clone https://github.com/boostorg/boost.git mydir

You can now `cd` into the newly created directory with

    cd mydir

This directory is called the "Boost root". All of the commands below assume that it is the current directory.

The above `git clone` commands download the default branch of the Boost Git repository, which is `master`. This is the current more-or-less stable version of Boost.

To verify this, issue the command

    git status

from the Boost root. This will output

    # On branch master
    nothing to commit, working directory clean

To download a specific release instead, such as 1.58.0, issue the following command after `git clone`, from the Boost root:

    git checkout boost-1.58.0

`git status` will now say

    # HEAD detached at boost-1.58.0
    nothing to commit, working directory clean

Then, download all the libraries:

    git submodule update --init

This step will take a while.

If all goes well, you will now have the complete contents of Boost's latest `master` branch (if you didn't `checkout` a specific release by name) or the corresponding Boost release (if you did).

You can switch between the `master` branch, the `develop` (unstable) branch, and a release, by issuing the following commands:

> For the `master` branch:

    git checkout master
    git pull
    git submodule update --init

> (`git pull` updates your local copy of the `master` branch from the server, in case it has changed since your initial checkout.)

> For the `develop` branch:

    git checkout develop
    git pull
    git submodule update --init

> For the `boost-1.58.0` release:

    git checkout boost-1.58.0
    git submodule update --init

> For the `boost-1.57.0` release:

    git checkout boost-1.57.0
    git submodule update --init

Note that, while the initial `git submodule update` is quite slow, as it needs to download all the libraries, the subsequent invocations are a lot faster.

Also note that if a new Boost library (`libs/convert`, for example) is present in, say, `master`, and you have it checked out, when you later switch to `boost-1.58.0`, where this library doesn't exist, Git will not delete `libs/convert`. In this case, `git status` will output

    # HEAD detached at boost-1.58.0
    # Untracked files:
    #   (use "git add <file>..." to include in what will be committed)
    #
    #       libs/convert/
    nothing added to commit but untracked files present (use "git add" to track)

and you will have to remove `libs/convert` by hand.

Once you have the Boost contents which you want to analyze for dependencies, proceed with the next step, building Boostdep.

### Building Boostdep

To build Boostdep, issue the following command from the Boost root:

    b2 tools/boostdep/build//install

This will build Boostdep from source using the default "toolset" (a Boost.Build term meaning "compiler") and if successful, place it into the `dist/bin` subdirectory. The command assumes that `b2` (the Boost.Build executable) is somewhere in your path. If you don't have `b2`, execute

    .\bootstrap

under Windows or

    ./bootstrap.sh

under Unix-like systems, which should build `b2` and place it into the current directory. You can then use `./b2` instead of `b2`.

### Running Boostdep

Once you have built Boostdep, execute it with the following command:

    dist/bin/boostdep

or

    dist\bin\boostdep

on Windows. The commands below are given as using `dist/bin/boostdep`; if you're using Windows, use `dist\bin\boostdep` instead.

This will print out the following help message:

    Usage:

        boostdep --list-modules
        boostdep --list-buildable
        boostdep [--track-sources] --list-dependencies

        boostdep [options] --module-overview
        boostdep [options] --module-levels
        boostdep [options] --module-weights

        boostdep [options] [--primary] <module>
        boostdep [options] --secondary <module>
        boostdep [options] --reverse <module>
        boostdep [options] --subset <module>
        boostdep [options] [--header] <header>

        [options]: [--track-sources] [--title <title>] [--footer <footer>] [--html]

(The 1.58.0 version of Boostdep has an unfortunate bug that causes the above output to be truncated after `boostdep --list-modules`. The rest of the functionality is intact though, so you can still use it as described.)

## Usage

### Simple Queries

To list the dependencies of a specific library, use the command

    dist/bin/boostdep library

For Boost.Filesystem, for example, type

    dist/bin/boostdep filesystem

This will print out something similar to the following:

    Primary dependencies for filesystem:

    assert:
        <boost/assert.hpp>
            from <boost/filesystem/operations.hpp>
            from <boost/filesystem/path_traits.hpp>

    config:
        <boost/config.hpp>
            from <boost/filesystem/config.hpp>
            from <boost/filesystem/convenience.hpp>
            from <boost/filesystem/fstream.hpp>
            from <boost/filesystem/operations.hpp>
            from <boost/filesystem/path.hpp>
            from <boost/filesystem/path_traits.hpp>
        ...

    functional:
        <boost/functional/hash_fwd.hpp>
            from <boost/filesystem/path.hpp>

    io:
        <boost/io/detail/quoted_manip.hpp>
            from <boost/filesystem/path.hpp>

    iterator:
        <boost/iterator/iterator_facade.hpp>
            from <boost/filesystem/path.hpp>
        ...

This lists the immediate dependencies of Boost.Filesystem. `assert:` is the library, `<boost/assert.hpp>` is the file that is being included, and `from <boost/filesystem/config.hpp>` shows where `<boost/assert.hpp>` is being included.

Boostdep names libraries (or modules) after their directory name. The `libs/filesystem` directory, for example, is the `filesystem` module. The `libs/numeric/conversion` directory is the `numeric~conversion` module, according to the Boostdep naming convention.

The reason forward slashes are replaced with tildes is that `numeric~conversion` is a valid file name, which makes generating HTML reports a bit easier.

To see where a given header resides and who includes it, type

    dist/bin/boostdep header

For `boost/filesystem.hpp`, for example, type

    dist/bin/boostdep boost/filesystem.hpp

This will print something along the lines of

    Inclusion report for <boost/filesystem.hpp> (in module filesystem):

        from spirit:
            <boost/spirit/home/x3/support/utility/testing.hpp>

What this tells you is that `boost/filesystem.hpp` is part of Boost.Filesystem and is only included once, from `<boost/spirit/home/x3/support/utility/testing.hpp>`. Other headers, such as `boost/shared_ptr.hpp`, are more widely used, as you can see if you try

    dist/bin/boostdep boost/shared_ptr.hpp

To print the reverse dependencies of a library, use

    dist/bin/boostdep --reverse library

For example,

    dist/bin/boostdep --reverse filesystem

will list which libraries depend on Boost.Filesystem:

    Reverse dependencies for filesystem:

    graph_parallel:
        <boost/filesystem/operations.hpp>
            from <boost/graph/distributed/adjlist/serialization.hpp>
        <boost/filesystem/path.hpp>
            from <boost/graph/distributed/adjlist/serialization.hpp>

    log:
        <boost/filesystem/config.hpp>
            from <boost/log/detail/config.hpp>
        <boost/filesystem/path.hpp>
            from <boost/log/sinks/event_log_backend.hpp>
            from <boost/log/sinks/text_file_backend.hpp>
            from <boost/log/sinks/text_multifile_backend.hpp>

    spirit:
        <boost/filesystem.hpp>
            from <boost/spirit/home/x3/support/utility/testing.hpp>
        <boost/filesystem/fstream.hpp>
            from <boost/spirit/home/x3/support/utility/testing.hpp>
        <boost/filesystem/path.hpp>
            from <boost/spirit/home/x3/support/utility/error_reporting.hpp>

    wave:
        <boost/filesystem/operations.hpp>
            from <boost/wave/util/cpp_include_paths.hpp>
            from <boost/wave/util/cpp_iterator.hpp>
            from <boost/wave/util/filesystem_compatibility.hpp>
        <boost/filesystem/path.hpp>
            from <boost/wave/cpp_context.hpp>
            from <boost/wave/util/cpp_include_paths.hpp>
            from <boost/wave/util/cpp_iterator.hpp>
            from <boost/wave/util/cpp_macromap.hpp>
            from <boost/wave/util/filesystem_compatibility.hpp>

### HTML reports

The primary purpose of Boostdep is to generate HTML dependency reports. In the typical case, two types of reports are generated: overviews that contain information for all modules, and per-module ones that list information for a specific library.

Boostdep can generate three types of the first kind of report: module overview, module levels and module weights. To generate a module overview, use the command

    dist/bin/boostdep --html --module-overview > module-overview.html

For a module level report, use

    dist/bin/boostdep --html --module-levels > module-levels.html

For a module weight report, use

    dist/bin/boostdep --html --module-weights > module-weights.html

In these reports, module names such as module are HTML links to `module.html`.

To make these links work as expected, you can generate HTML reports for each module as follows:

    dist/bin/boostdep --title "Dependency Report for module" --html --primary module --secondary module --reverse module > module.html

This step can be automated if you generate a module list first with

    dist/bin/boostdep --list-modules > list-modules.txt

that will contain one module name per line, and then use a script to issue the previous command for each module name.

For more information about the Boostdep options and commands, see the Reference section.

For an example of a report generation script, see the file `tools/boostdep/examples/report.bat`. This is a Windows batch file, but translating it to a Unix-style shell script should be straightforward.

For convenience, the contents of `tools/boostdep/examples/report.bat` are given below:

    SET BOOSTDEP=dist\bin\boostdep.exe

    FOR /f %%i IN ('git rev-parse HEAD') DO @SET REV=%%i

    FOR /f %%i IN ('git rev-parse --short HEAD') DO @SET SHREV=%%i

    FOR /f %%i IN ('git rev-parse --abbrev-ref HEAD') DO @SET BRANCH=%%i

    SET FOOTER=Generated on %DATE% %TIME% from revision %REV% on branch '%BRANCH%'

    SET OUTDIR=..\report-%BRANCH%-%SHREV%

    mkdir %OUTDIR%

    %BOOSTDEP% --list-modules > %OUTDIR%\list-modules.txt

    %BOOSTDEP% --footer "%FOOTER%" --html --module-overview > %OUTDIR%\module-overview.html
    %BOOSTDEP% --footer "%FOOTER%" --html --module-levels > %OUTDIR%\module-levels.html
    %BOOSTDEP% --footer "%FOOTER%" --html --module-weights > %OUTDIR%\module-weights.html

    FOR /f %%i IN (%OUTDIR%\list-modules.txt) DO %BOOSTDEP% --title "Dependency Report for %%i" --footer "%FOOTER%" --html --primary %%i --secondary %%i --reverse %%i > %OUTDIR%%%i.html

## Reference

### --list-modules

`boostdep --list-modules` prints the module list. Boostdep considers a subdirectory of `libs` a module if it contains an `include` subdirectory.

This command is typically used from scripts which then use the list to execute a command for each module.

### --list-buildable

`boostdep --list-buildable` prints a list of the modules that require building. Boostdep considers a module to require building if it contains subdirectories named `build` and `src`.

This command is typically used from scripts.

### --list-dependencies

`boostdep --list-dependencies` prints a module list in which each line is of the form

    module -> dependency1 dependency2 ...

By default, only the `include` directory is scanned for `#include` directives. If the option `--track-sources` is given, the `src` directory is also scanned.

This command is typically used from scripts. The output is virtually identical to `--module-overview` in plain text, but slightly more machine-friendly.

### --module-overview

`boostdep --module-overview` generates a module overview, in plain text or HTML. The plain text output is of the form

    Module Overview:

    accumulators -> array assert circular_buffer concept_check config core fusion iterator mpl numeric~conversion numeric~ublas parameter preprocessor range static_assert throw_exception tuple type_traits typeof
    algorithm -> array assert bind concept_check config core exception function iterator mpl range regex static_assert tuple type_traits unordered
    align -> assert config core static_assert throw_exception

whereas the HTML output is similar to

> Module Overview

> accumulators

> ⇢ array assert circular_buffer concept_check config core fusion iterator mpl numeric~conversion numeric~ublas parameter preprocessor range static_assert throw_exception tuple type_traits typeof

where accumulators is a link to `accumulators.html`.

As before, if `--track-sources` is given, the `src` subdirectory is scanned for `#include` directives.

HTML output is enabled by the `--html` option. The `--title` and `--footer` options set the HTML `<title>` and the page footer and need to precede `--html`, like in the following example:

    dist/bin/boostdep --title "Module Overview" --footer "Generated on 21.05.2015 20:53:11" --html --module-overview > module-overview.html

### --module-levels

`boostdep --module-levels` generates a report that groups modules by level. Levels are determined in such a way so that a module of level `N` never depends on modules of levels greater than `N`, and in the absence of cyclic dependencies, doesn't depend on other modules of level `N`. It takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Module Levels" --footer "Generated on 21.05.2015 20:53:11" --html --module-levels > module-levels.html

### --module-weights

`boostdep --module-weights` generates a report that lists modules by weight. A module weight is the total number of its dependencies. This includes the indirect dependencies.

`--module-weights` takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Module Weights" --footer "Generated on 21.05.2015 20:53:11" --html --module-weights > module-weights.html

### --primary

`boostdep --primary module` lists the primary (direct) dependencies of module. It takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Primary Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --primary filesystem > filesystem-primary.html

### --secondary

`boostdep --secondary module` lists the secondary (indirect) dependencies of module. It takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Secondary Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --secondary filesystem > filesystem-secondary.html

You can combine `--primary` and `--secondary` in one invocation.

    dist/bin/boostdep --title "Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --primary filesystem --secondary filesystem > filesystem.html

### --reverse

`boostdep --reverse module` lists the reverse dependencies of module, that is, it lists which modules depend on module. It takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Reverse Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --reverse filesystem > filesystem-reverse.html

You can combine `--reverse` with `--primary` and `--secondary` for a complete module report.

    dist/bin/boostdep --title "Dependency Report for filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --primary filesystem --secondary filesystem --reverse filesystem > filesystem.html

### --subset

`boostdep --subset module` lists the subset dependencies of module, that is, it lists which modules comprise the subset which module requires in order to be usable. The dependencies are determined by tracing the `#include` directives starting from module's headers.

The difference between using the modules reported by `--subset` and those reported by the sum of `--primary` and `--secondary` is that the former only guarantees that module will be usable, whereas the latter guarantees it for every module in the subset.

`--subset` takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Subset Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --subset filesystem > filesystem-subset.html

You can combine `--subset` with the other module report options.

### --header

`boostdep --header header` creates an inclusion report for header. It takes the same options as `--module-overview`.

    dist/bin/boostdep --title "Inclusion Report for <boost/shared_ptr.hpp>" --footer "Generated on 21.05.2015 20:53:11" --html --header boost/shared_ptr.hpp > header-boost-shared_ptr.html

### --track-sources

The `--track-sources` option instructs Boostdep to scan the `src` library subdirectory for `#include` directives. By default, only the `include` subdirectory is scanned.

### --title

`--title title` sets the contents of the HTML `<title>` tag. It must precede `--html` to have an effect.

### --footer

`--footer footer` sets the page footer text. It has no effect if `--html` is not given.

### --html

`--html` switches to HTML output mode (the default is plain text). It must precede the commands that generate output.

Last revised: March 04, 2016 at 11:24:14 GMT |