## Dependent Targets

When a building a target `X` depends on first building another target `Y` (such as a library that must be linked with X), `Y` is called a dependency of `X` and `X` is termed a dependent of `Y`.

To get a feeling of target dependencies, let's continue the above example and see how `top/app/Jamfile` can use libraries from `top/util/foo`. If `top/util/foo/Jamfile` contains

    lib bar : bar.cpp ;

then to use this library in `top/app/Jamfile`, we can write:

    exe app : app.cpp ../util/foo//bar ;

While `app.cpp` refers to a regular source file, `../util/foo//bar` is a reference to another target: a library `bar` declared in the Jamfile at `../util/foo`.

| Tip
Some other build system have special syntax for listing dependent libraries, for example `LIBS` variable. In Boost.Build, you just add the library to the list of sources.

Suppose we build `app` with:

    bjam app optimization=full define=USE_ASM

Which properties will be used to build `foo`? The answer is that some features are propagated—Boost.Build attempts to use dependencies with the same value of propagated features. The `<optimization>` feature is propagated, so both `app` and `foo` will be compiled with full optimization. But `<define>` is not propagated: its value will be added as-is to the compiler flags for `a.cpp`, but won't affect `foo`.

Let's improve this project further. The library probably has some headers that must be used when compiling `app.cpp`. We could manually add the necessary `#include` paths to `app`'s requirements as values of the `<include>` feature, but then this work will be repeated for all programs that use `foo`. A better solution is to modify `util/foo/Jamfile` in this way:

    project
        : usage-requirements <include>.
        ;

    lib foo : foo.cpp ;

Usage requirements are applied not to the target being declared but to its dependents. In this case, `<include>.` will be applied to all targets that directly depend on `foo`.

Another improvement is using symbolic identifiers to refer to the library, as opposed to `Jamfile` location. In a large project, a library can be used by many targets, and if they all use `Jamfile` location, a change in directory organization entails much work. The solution is to use project ids—symbolic names not tied to directory layout. First, we need to assign a project id by adding this code to `Jamroot`:

    use-project /library-example/foo : util/foo ;

Second, we modify `app/Jamfile` to use the project id:

    exe app : app.cpp /library-example/foo//bar ;

The `/library-example/foo//bar` syntax is used to refer to the target `bar` in the project with id `/library-example/foo`. We've achieved our goal—if the library is moved to a different directory, only `Jamroot` must be modified. Note that project ids are global—two Jamfiles are not allowed to assign the same project id to different directories.

| Tip

If you want all applications in some project to link to a certain library, you can avoid having to specify it directly the sources of every target by using the `<library>` property. For example, if `/boost/filesystem//fs` should be linked to all applications in your project, you can add `<library>/boost/filesystem//fs` to the project's requirements, like this:

    project
       : requirements <source>/boost/filesystem//fs
       ;