The Boost.Build System
Vladimir Prus
Computer Systems Laboratory
Moscow State University, CS department
Moscow, Russia
vladimir.prus@gmail.com
Abstract—Boost.Build is a new build system with unique
approach to portability. This paper discusses the underlying
requirements, the key design decisions, and the lessons learned
during several years of development. We also review other
contemporary build systems, and why they fail to meet the same
requirements.
I. INTRODUCTION
For software projects using compiled languages (primarily
C and C++), build system is the key element of infrastructure.
Mature tools such as GNU Make[1] or GNU Automake[2]
exist. However, those tools are relatively low level, and hard
to master. They also have limited portability. For that reason,
many software project do custom work on build system level.
One such project is C++ Boost [3].
C++ Boost is a popular collection of C++ libraries, many
of which are either included in the next revision of the C++
Standard or planned for inclusion[4], [5]. This unique position
attracts a lot of users, who, in turn, use a wide variety of
operating systems and differently-configured environments.
This differs from most commercial projects — which target
a few platforms that are important from business perspective,
and are built in a well-controlled environment. This is also
different from most open-source projects — which tend to
focus on GNU/Linux environment. Developers’ background
also considerably differs — a person who is expert in C++ is
not necessary an expert in different operating systems.
This diversity in user and developer base lead to the
following requirements for a build system:
1) “Write once, build everywhere”. If a library builds on
one platform, it should be very likely that it builds on all
other platforms supported by the build system. It follows
that build description should be relatively high-level, and
avoid any system- or compiler- specific details, such as
file extensions, compiler options or command-line shell
syntax details.
2) Extensibility. Adding support for a new compiler or a
platform should not require changing build system core
or build descriptions for individual libraries. Ideally, user
would have to write a new module and provide it to the
build system.
3) Multiple variants. The build system may not require that
the build properties for the entire project are specified
up-front, during special “configure” step, and then re-
quire that all build products be removed before changing
build properties. Instead, it should be possible to change
build properties without full rebuild. Such change may
happen at three levels:
a) Between different parts of the project. The simplest
example is compiling a specific source file with an
additional compiler option. More complex example
is building a specific module as a static library, and
another as a shared library. It should be possible to
change every aspect of the build process — even
including the used compiler.
b) Between different builds. For example, one may
originally build a project in release mode for test-
ing and, after discovering a bug, wish to initiate
a build in debug mode. It would be wasteful to
remove the previously built object files, so the
build system must arrange for debug and release
products to be placed in different directories. The
mechanism should not be restricted to just debug
and release builds, but apply to any build proper-
ties.
c) Within one build. This means that one invocation
of the build system may produce several variants
of a build product — for example, static and shared
versions of the same library.
This paper describes Boost.Build[6] — a build system devel-
oped to meet the above requirements. Section 2 will describe
key concepts and mechanisms of Boost.Build. In section 3 we
review the lessons learned during development as well as some
unexpected drawbacks. Section 4 discusses other contempo-
rary build tools, and why they could not be used. Section
5 summarizes the article and suggests future development
directions.
II. DESIGN CONCEPTS
The best way to explain the key design elements of
Boost.Build is by following a few steps of gradual refinements,
starting from a classic tool — GNU Make. In GNU Make, a
user directly defines a set of targets, where a target is an object
that has:
• a name
• a set of dependency targets
• a command to build the target
Consider this example:
a.o: a.c
g++ -o a.o -g a.c