2 Copyright 2015 Peter Dimov
4 Distributed under the Boost Software License, Version 1.0.
6 See accompanying file LICENSE_1_0.txt or copy at
7 http://boost.org/LICENSE_1_0.txt
13 [copyright 2014, 2015, 2016 Peter Dimov]
14 [license Distributed under the
15 [@http://boost.org/LICENSE_1_0.txt Boost Software License, Version 1.0].
19 [template simplesect[title]
20 [block '''<simplesect><title>'''[title]'''</title>''']]
22 [template endsimplesect[]
23 [block '''</simplesect>''']]
25 [section Introduction]
27 /Boostdep/ is a tool for generating Boost dependency reports. It scans
28 the header or source files of the Boost libraries for `#include`
29 directives, builds a dependency graph from this information and outputs
30 its findings in plain text or HTML.
32 [section Modular Boost]
34 /Boostdep/ requires the so-called "modular Boost" directory structure.
36 If you already have a [@https://svn.boost.org/trac/boost/wiki/ModularBoost
37 modular Boost installation], you can skip this section. Otherwise, read on.
39 Boost libraries reside in subdirectories under the =libs= directory. For
40 example, the contents of the Boost.Filesystem library are in =libs/filesystem=.
41 This includes the build scripts (in =libs/filesystem/build=), the source files
42 (in =libs/filesystem/src=), the tests (in =libs/filesystem/test=), the documentation
43 (in =libs/filesystem/doc=), and so on.
45 In the past, when Boost used SVN as its version control system, the header files
46 were an exception. The header files of all libraries resided in the =boost= subdirectory,
47 and it wasn't possible to accurately determine which header belonged to which library.
49 When Boost moved to Git for version control, header files were moved to their corresponding
50 libraries, into an =include= subdirectory. The header files of Boost.Filesystem are now in
51 =libs/filesystem/include=.
53 For compatibility, =boost= is now a "virtual" directory, containing links to the headers.
54 It's maintained automatically by Boost.Build. (The command =b2 headers= creates or recreates
55 the contents of the =boost= directory.)
57 This new structure allows /Boostdep/ to determine that, when faced with an
58 `#include <boost/filesystem.hpp>` directive, that this header is part of Boost.Filesystem, and
59 that therefore, the current library being scanned depends on Boost.Filesystem.
61 Unfortunately, Boost releases do not have this structure. For backward compatibility, they
62 have an old-style =boost= directory containing all header files, whereas the per-library =include=
63 subdirectories are missing. Therefore, /Boostdep/ will not work with a downloaded Boost release.
65 To use /Boostdep/, you will have to clone the Boost Git repository instead. To do that, execute the
69 git clone https://github.com/boostorg/boost.git boost
72 This will download the Boost "superproject" (the master project, without any libraries) and place it
73 into the subdirectory =boost= of the current directory. To override the directory name, pass it as a
74 second argument instead of =boost=:
77 git clone https://github.com/boostorg/boost.git /mydir/
80 You can now =cd= into the newly created directory with
86 This directory is called the "Boost root". All of the commands below assume that it is the current directory.
88 The above =git clone= commands download the default branch of the Boost Git repository, which is =master=.
89 This is the current more-or-less stable version of Boost.
91 To verify this, issue the command
97 from the Boost root. This will output
101 nothing to commit, working directory clean
104 To download a specific release instead, such as 1.58.0, issue the following command after =git clone=, from
108 git checkout boost-1.58.0
111 =git status= will now say
114 # HEAD detached at boost-1.58.0
115 nothing to commit, working directory clean
118 Then, download all the libraries:
121 git submodule update --init
124 This step will take a while.
126 If all goes well, you will now have the complete contents of Boost's latest =master= branch (if you didn't =checkout=
127 a specific release by name) or the corresponding Boost release (if you did).
129 You can switch between the =master= branch, the =develop= (unstable) branch, and a release, by issuing the following
132 [:For the =master= branch:]
137 git submodule update --init
140 [:(=git pull= updates your local copy of the =master= branch from the server, in case it has changed since your initial
143 [:For the =develop= branch:]
148 git submodule update --init
151 [:For the =boost-1.58.0= release:]
154 git checkout boost-1.58.0
155 git submodule update --init
158 [:For the =boost-1.57.0= release:]
161 git checkout boost-1.57.0
162 git submodule update --init
165 Note that, while the initial =git submodule update= is quite slow, as it needs to download all the libraries, the
166 subsequent invocations are a lot faster.
168 Also note that if a new Boost library (=libs/convert=, for example) is present in, say, =master=, and you have it checked out,
169 when you later switch to =boost-1.58.0=, where this library doesn't exist, Git will not delete =libs/convert=. In this case,
170 =git status= will output
173 # HEAD detached at boost-1.58.0
175 # (use "git add <file>..." to include in what will be committed)
178 nothing added to commit but untracked files present (use "git add" to track)
181 and you will have to remove =libs/convert= by hand.
183 Once you have the Boost contents which you want to analyze for dependencies, proceed with the next step, building /Boostdep/.
187 [section Building Boostdep]
189 To build /Boostdep/, issue the following command from the Boost root:
192 b2 tools/boostdep/build//install
195 This will build /Boostdep/ from source using the default "toolset" (a Boost.Build term meaning "compiler") and if successful,
196 place it into the =dist/bin= subdirectory. The command assumes that =b2= (the Boost.Build executable) is somewhere in your path.
197 If you don't have =b2=, execute
209 under Unix-like systems, which should build =b2= and place it into the current directory. You can then use =./b2= instead of =b2=.
213 [section Running Boostdep]
215 Once you have built /Boostdep/, execute it with the following command:
227 on Windows. The commands below are given as using =dist/bin/boostdep=; if you're using Windows, use =dist\bin\boostdep= instead.
229 This will print out the following help message:
234 boostdep --list-modules
235 boostdep --list-buildable
236 boostdep \[--track-sources\] --list-dependencies
238 boostdep \[options\] --module-overview
239 boostdep \[options\] --module-levels
240 boostdep \[options\] --module-weights
242 boostdep \[options\] \[--primary\] <module>
243 boostdep \[options\] --secondary <module>
244 boostdep \[options\] --reverse <module>
245 boostdep \[options\] --subset <module>
246 boostdep \[options\] \[--header\] <header>
248 \[options\]: \[--track-sources\] \[--title <title>\] \[--footer <footer>\] \[--html\]
251 (The 1.58.0 version of /Boostdep/ has an unfortunate bug that causes the above output to be truncated after =boostdep --list-modules=.
252 The rest of the functionality is intact though, so you can still use it as described.)
260 [section Simple Queries]
262 To list the dependencies of a specific library, use the command
265 dist/bin/boostdep /library/
268 For Boost.Filesystem, for example, type
271 dist/bin/boostdep filesystem
274 This will print out something similar to the following:
277 Primary dependencies for filesystem:
281 from <boost/filesystem/operations.hpp>
282 from <boost/filesystem/path_traits.hpp>
286 from <boost/filesystem/config.hpp>
287 from <boost/filesystem/convenience.hpp>
288 from <boost/filesystem/fstream.hpp>
289 from <boost/filesystem/operations.hpp>
290 from <boost/filesystem/path.hpp>
291 from <boost/filesystem/path_traits.hpp>
295 <boost/functional/hash_fwd.hpp>
296 from <boost/filesystem/path.hpp>
299 <boost/io/detail/quoted_manip.hpp>
300 from <boost/filesystem/path.hpp>
303 <boost/iterator/iterator_facade.hpp>
304 from <boost/filesystem/path.hpp>
308 This lists the immediate dependencies of Boost.Filesystem. =assert:= is the library,
309 =<boost/assert.hpp>= is the file that is being included, and =from <boost/filesystem/config.hpp>=
310 shows where =<boost/assert.hpp>= is being included.
312 /Boostdep/ names libraries (or modules) after their directory name. The =libs/filesystem=
313 directory, for example, is the =filesystem= module. The =libs/numeric/conversion= directory
314 is the =numeric~conversion= module, according to the /Boostdep/ naming convention.
316 The reason forward slashes are replaced with tildes is that =numeric~conversion= is a valid
317 file name, which makes generating HTML reports a bit easier.
319 To see where a given header resides and who includes it, type
322 dist/bin/boostdep /header/
325 For =boost/filesystem.hpp=, for example, type
328 dist/bin/boostdep boost/filesystem.hpp
331 This will print something along the lines of
334 Inclusion report for <boost/filesystem.hpp> (in module filesystem):
337 <boost/spirit/home/x3/support/utility/testing.hpp>
340 What this tells you is that =boost/filesystem.hpp= is part of Boost.Filesystem and is only
341 included once, from =<boost/spirit/home/x3/support/utility/testing.hpp>=. Other headers,
342 such as =boost/shared_ptr.hpp=, are more widely used, as you can see if you try
345 dist/bin/boostdep boost/shared_ptr.hpp
348 To print the reverse dependencies of a library, use
351 dist/bin/boostdep --reverse /library/
357 dist/bin/boostdep --reverse filesystem
360 will list which libraries depend on Boost.Filesystem:
363 Reverse dependencies for filesystem:
366 <boost/filesystem/operations.hpp>
367 from <boost/graph/distributed/adjlist/serialization.hpp>
368 <boost/filesystem/path.hpp>
369 from <boost/graph/distributed/adjlist/serialization.hpp>
372 <boost/filesystem/config.hpp>
373 from <boost/log/detail/config.hpp>
374 <boost/filesystem/path.hpp>
375 from <boost/log/sinks/event_log_backend.hpp>
376 from <boost/log/sinks/text_file_backend.hpp>
377 from <boost/log/sinks/text_multifile_backend.hpp>
380 <boost/filesystem.hpp>
381 from <boost/spirit/home/x3/support/utility/testing.hpp>
382 <boost/filesystem/fstream.hpp>
383 from <boost/spirit/home/x3/support/utility/testing.hpp>
384 <boost/filesystem/path.hpp>
385 from <boost/spirit/home/x3/support/utility/error_reporting.hpp>
388 <boost/filesystem/operations.hpp>
389 from <boost/wave/util/cpp_include_paths.hpp>
390 from <boost/wave/util/cpp_iterator.hpp>
391 from <boost/wave/util/filesystem_compatibility.hpp>
392 <boost/filesystem/path.hpp>
393 from <boost/wave/cpp_context.hpp>
394 from <boost/wave/util/cpp_include_paths.hpp>
395 from <boost/wave/util/cpp_iterator.hpp>
396 from <boost/wave/util/cpp_macromap.hpp>
397 from <boost/wave/util/filesystem_compatibility.hpp>
402 [section HTML reports]
404 The primary purpose of /Boostdep/ is to generate HTML dependency reports. In
405 the typical case, two types of reports are generated: overviews that contain
406 information for all modules, and per-module ones that list information for a
409 /Boostdep/ can generate three types of the first kind of report: module overview,
410 module levels and module weights. To generate a module overview, use the command
413 dist/bin/boostdep --html --module-overview > module-overview.html
416 For a module level report, use
419 dist/bin/boostdep --html --module-levels > module-levels.html
422 For a module weight report, use
425 dist/bin/boostdep --html --module-weights > module-weights.html
428 In these reports, module names such as /module/ are HTML links to [^/module/.html].
430 To make these links work as expected, you can generate HTML reports for each module
434 dist/bin/boostdep --title "Dependency Report for /module/" --html --primary /module/ --secondary /module/ --reverse /module/ > /module/.html
437 This step can be automated if you generate a module list first with
440 dist/bin/boostdep --list-modules > list-modules.txt
443 that will contain one module name per line, and then use a script to issue the previous
444 command for each module name.
446 For more information about the /Boostdep/ options and commands, see the [link boostdep.reference Reference] section.
448 For an example of a report generation script, see the file =tools/boostdep/examples/report.bat=.
449 This is a Windows batch file, but translating it to a Unix-style shell script should be
452 For convenience, the contents of =tools/boostdep/examples/report.bat= are given below:
455 SET BOOSTDEP=dist\bin\boostdep.exe
457 FOR /f %%i IN ('git rev-parse HEAD') DO @SET REV=%%i
459 FOR /f %%i IN ('git rev-parse --short HEAD') DO @SET SHREV=%%i
461 FOR /f %%i IN ('git rev-parse --abbrev-ref HEAD') DO @SET BRANCH=%%i
463 SET FOOTER=Generated on %DATE% %TIME% from revision %REV% on branch '%BRANCH%'
465 SET OUTDIR=..\report-%BRANCH%-%SHREV%
469 %BOOSTDEP% --list-modules > %OUTDIR%\list-modules.txt
471 %BOOSTDEP% --footer "%FOOTER%" --html --module-overview > %OUTDIR%\module-overview.html
472 %BOOSTDEP% --footer "%FOOTER%" --html --module-levels > %OUTDIR%\module-levels.html
473 %BOOSTDEP% --footer "%FOOTER%" --html --module-weights > %OUTDIR%\module-weights.html
475 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
484 [section --list-modules]
485 =boostdep --list-modules= prints the module list. /Boostdep/ considers a
486 subdirectory of =libs= a module if it contains an =include= subdirectory.
488 This command is typically used from scripts which then use the list to execute
489 a command for each module.
492 [section --list-buildable]
493 =boostdep --list-buildable= prints a list of the modules that require building.
494 /Boostdep/ considers a module to require building if it contains subdirectories
495 named =build= and =src=.
497 This command is typically used from scripts.
501 [section --list-dependencies]
502 =boostdep --list-dependencies= prints a module list in which each line is of the
506 module -> dependency1 dependency2 /.../
509 By default, only the =include= directory is scanned for `#include` directives. If
510 the option =--track-sources= is given, the =src= directory is also scanned.
512 This command is typically used from scripts. The output is virtually identical to
513 =--module-overview= in plain text, but slightly more machine-friendly.
516 [section --module-overview]
517 =boostdep --module-overview= generates a module overview, in plain text or HTML. The
518 plain text output is of the form
523 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
524 algorithm -> array assert bind concept_check config core exception function iterator mpl range regex static_assert tuple type_traits unordered
525 align -> assert config core static_assert throw_exception
528 whereas the HTML output is similar to
535 \u21E2 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
538 where /accumulators/ is a link to =accumulators.html=.
540 As before, if =--track-sources= is given, the =src= subdirectory is scanned for `#include` directives.
542 HTML output is enabled by the =--html= option. The =--title= and =--footer= options set the HTML =<title>=
543 and the page footer and need to precede =--html=, like in the following example:
546 dist/bin/boostdep --title "Module Overview" --footer "Generated on 21.05.2015 20:53:11" --html --module-overview > module-overview.html
551 [section --module-levels]
553 =boostdep --module-levels= generates a report that groups modules by level. Levels are determined in such
554 a way so that a module of level =N= never depends on modules of levels greater than =N=, and in the absence
555 of cyclic dependencies, doesn't depend on other modules of level =N=. It takes the same options as
559 dist/bin/boostdep --title "Module Levels" --footer "Generated on 21.05.2015 20:53:11" --html --module-levels > module-levels.html
564 [section --module-weights]
566 =boostdep --module-weights= generates a report that lists modules by weight. A module weight is the total number of
567 its dependencies. This includes the indirect dependencies.
569 =--module-weights= takes the same options as =--module-overview=.
572 dist/bin/boostdep --title "Module Weights" --footer "Generated on 21.05.2015 20:53:11" --html --module-weights > module-weights.html
579 [^boostdep --primary /module/] lists the primary (direct) dependencies of /module/. It takes the same options as =--module-overview=.
582 dist/bin/boostdep --title "Primary Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --primary filesystem > filesystem-primary.html
587 [section --secondary]
589 [^boostdep --secondary /module/] lists the secondary (indirect) dependencies of /module/. It takes the same options as =--module-overview=.
592 dist/bin/boostdep --title "Secondary Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --secondary filesystem > filesystem-secondary.html
595 You can combine =--primary= and =--secondary= in one invocation.
598 dist/bin/boostdep --title "Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --primary filesystem --secondary filesystem > filesystem.html
605 [^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=.
608 dist/bin/boostdep --title "Reverse Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --reverse filesystem > filesystem-reverse.html
611 You can combine =--reverse= with =--primary= and =--secondary= for a complete module report.
614 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
621 [^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.
622 The dependencies are determined by tracing the =#include= directives starting from /module/'s headers.
624 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
625 that /module/ will be usable, whereas the latter guarantees it for every module in the subset.
627 =--subset= takes the same options as =--module-overview=.
630 dist/bin/boostdep --title "Subset Dependencies of filesystem" --footer "Generated on 21.05.2015 20:53:11" --html --subset filesystem > filesystem-subset.html
633 You can combine =--subset= with the other module report options.
639 [^boostdep --header /header/] creates an inclusion report for /header/. It takes the same options as =--module-overview=.
642 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
647 [section --track-sources]
649 The =--track-sources= option instructs /Boostdep/ to scan the =src= library subdirectory for `#include` directives. By default,
650 only the =include= subdirectory is scanned.
656 [^--title /title/] sets the contents of the HTML =<title>= tag. It must precede =--html= to have an effect.
662 [^--footer /footer/] sets the page footer text. It has no effect if =--html= is not given.
668 =--html= switches to HTML output mode (the default is plain text). It must precede the commands that generate output.