So far we have only considered examples with one project, with
one user-written Boost.Jam file,
Jamroot. A typical
large codebase would be composed of many projects organized into a tree.
The top of the tree is called the project root.
Every subproject is defined by a file called
in a descendant directory of the project root. The parent project of a
subproject is defined by the nearest
Jamroot file in an ancestor directory. For example,
in the following directory layout:
top/ | +-- Jamroot | +-- app/ | | | +-- Jamfile | `-- app.cpp | `-- util/ | +-- foo/ . | . +-- Jamfile . `-- bar.cpp
the project root is
top/. The projects in
immediate children of the root project.
When we refer to a “Jamfile,” set in normal
type, we mean a file called either
Jamroot. When we need to be more
specific, the filename will be set as
Projects inherit all attributes (such as requirements)
from their parents. Inherited requirements are combined with
any requirements specified by the subproject.
For example, if
in its requirements, then all of its subprojects will have it in their requirements, too. Of course, any project can add include paths to those specified by its parents.  More details can be found in the section called “Projects”.
Invoking b2 without explicitly specifying
any targets on the command line builds the project rooted in the
current directory. Building a project does not automatically
cause its subprojects to be built unless the parent project's
Jamfile explicitly requests it. In our example,
top/Jamroot might contain:
build-project app ;
which would cause the project in
to be built whenever the project in
built. However, targets in
will be built only if they are needed by targets in