| Home | Libraries | People | FAQ | More

## Builtin target types

### Programs

Programs are created using the `exe` rule, which follows the common syntax. For example:

    exe hello : hello.cpp some_library.lib /some_project//library
              : <threading>multi
              ;

This will create an executable file from the sources -- in this case, one C++ file, one library file present in the same directory, and another library that is created by Boost.Build. Generally, sources can include C and C++ files, object files and libraries. Boost.Build will automatically try to convert targets of other types.

### Tip

On Windows, if an application uses dynamic libraries, and both the application and the libraries are built by Boost.Build, its not possible to immediately run the application, because the `PATH` environment variable should include the path to the libraries. It means you have to either add the paths manually, or place the application and the libraries to the same directory, for example using the stage rule.

### Libraries

Libraries are created using the `lib` rule, which follows the common syntax. For example:

    lib helpers : helpers.cpp : <include>boost : : <include>. ;

In the most common case, the `lib` creates a library from the specified sources. Depending on the value of <link> feature the library will be either static or shared. There are two other cases. First is when the library is installed somewhere in compiler's search paths, and should be searched by the compiler (typically, using the `-l` option). The second case is where the library is available as a prebuilt file and the full path is known.

The syntax for these case is given below:

    lib z : : <name>z <search>/home/ghost ;
    lib compress : : <file>/opt/libs/compress.a ;

The `name` property specifies the name that should be passed to the `-l` option, and the `file` property specifies the file location. The `search` feature specifies paths in which to search for the library. That feature can be specified several times, or it can be omitted, in which case only default compiler paths will be searched.

The difference between using the `file` feature as opposed to the `name` feature together with the `search` feature is that `file` is more precise. A specific file will be used. On the other hand, the `search` feature only adds a library path, and the `name` feature gives the basic name of the library. The search rules are specific to the linker. For example, given these definition:

    lib a : : <variant>release <file>/pool/release/a.so ;
    lib a : : <variant>debug <file>/pool/debug/a.so ;
    lib b : : <variant>release <file>/pool/release/b.so ;
    lib b : : <variant>debug <file>/pool/debug/b.so ;

It's possible to use release version of `a` and debug version of `b`. Had we used the `name` and `search` features, the linker would always pick either release or debug versions.

For convenience, the following syntax is allowed:

    lib z ;
    lib gui db aux ;

and is does exactly the same as:

    lib z : : <name>z ;
    lib gui : : <name>gui ;
    lib db : : <name>db ;
    lib aux : : <name>aux ;

When a library uses another library you should put that another library in the list of sources. This will do the right thing in all cases. For portability, you should specify library dependencies even for searched and prebuilt libraries, othewise, static linking on Unix won't work. For example:

    lib z ;
    lib png : z : <name>png ;

### Note

When a library (say, `a`), that has another library, (say, `b`) is linked dynamically, the `b` library will be incorporated in `a`. (If `b` is dynamic library as well, then `a` will only refer to it, and not include any extra code.) When the `a` library is linked statically, Boost.Build will assure that all executables that link to `a` will also link to `b`.

One feature of Boost.Build that is very important for libraries is usage requirements. For example, if you write:

    lib helpers : helpers.cpp : : : <include>. ;

then the compiler include path for all targets that use `helpers` will contain the directory where the target is defined.path to "helpers.cpp". The user only needs to add `helpers` to the list of sources, and needn't consider the requirements its use imposes on a dependent target. This feature greatly simplifies Jamfiles.

### Note

If you don't want shared libraries to include all libraries that are specified in sources (especially statically linked ones), you'd need to use the following:

    lib b : a.cpp ;
    lib a : a.cpp : <use>b : : <library>b ;

This specifies that `a` uses `b`, and causes all executables that link to `a` also link to `b`. In this case, even for shared linking, the `a` library won't even refer to `b`.

### Alias

The `alias` rule follows the common syntax. For example:

    alias core : im reader writer ;

will build the sources and return the generated source targets without modification.

The `alias` rule is a convenience tool. If you often build the same group of targets at the same time, you can define an alias to save typing.

Another use of the `alias` rule is to change build properties. For example, if you always want static linking for a specific C++ Boost library, you can write the following:

    alias threads : /boost/thread//boost_thread : <link>static ;

and use only the `threads` alias in your Jamfiles.

You can also specify usage requirements for the `alias` target. If you write the following:

    alias header_only_library : : : :  <include>/usr/include/header_only_library ;

then using `header_only_library` in sources will only add an include path. Also note that when there are some sources, their usage requirements are propagated, too. For example:

    lib lib : lib.cpp : : : <include>. ;
    alias lib_alias ;
    exe main : main.cpp lib_alias ;

will compile `main.cpp` with the additional include.

### Installing

For installing a built target you should use the `install` rule, which follows the common syntax. For example:

    install dist : hello helpers ;

will cause the targets `hello` and `helpers` to be moved to the `dist` directory, relative to Jamfile's directory. The directory can be changed with the `location` property:

    install dist : hello helpers : <location>/usr/bin ;

While you can achieve the same effect by changing the target name to `/usr/bin`, using the `location` property is better, because it allows you to use a memnonic target name.

The `location` property is especially handy when the location is not fixed, but depends on build variant or environment variables:

    install dist : hello helpers : <variant>release:<location>dist/release
                                 <variant>debug:<location>dist/debug ;
    install dist2 : hello helpers : <location>$(DIST) ;

See also conditional properties and environment variables

Specifying the names of all libraries to install can be boring. The `install` allows you to specify only the top-level executable targets to install, and automatically install all dependencies:

    install dist : hello
               : <install-dependencies>on <install-type>EXE
                 <install-type>LIB
               ;

will find all targets that `hello` depends on, and install all of the which are either executables or libraries. More specifically, for each target, other targets that were specified as sources or as dependency properties, will be recursively found. One exception is that targets referred with the `use` feature are not considered, because that feature is typically used to refer to header-only libraries. If the set of target types is specified, only targets of that type will be installed, otherwise, all found target will be installed.

The `alias` rule can be used when targets must be installed into several directories:

    install install : install-bin install-lib ;
    install install-bin : applications : /usr/bin ;
    install install-lib : helper : /usr/lib ;

Because the `install` rule just copies targets, most free features [6] have no effect when used in requirements of the `install`. The only two which matter are `dependency` and, on Unix, `dll-path`.

### Note

(Unix specific). On Unix, executables built with Boost.Build typically contain the list of paths to all used dynamic libraries. For installing, this is not desired, so Boost.Build relinks the executable with an empty list of paths. You can also specify additional paths for installed executables with the `dll-path` feature.

### Testing

Boost.Build has convenient support for running unit tests. The simplest way is the `unit-test` rule, which follows the common syntax. For example:

    unit-test helpers_test : helpers_test.cpp helpers ;

The `unit-test` rule behaves like the `exe` rule, but after the executable is created it is run. If the executable returns an error code, the build system will also return an error and will try running the executable on the next invocation until it runs successfully. This behaviour ensures that you can't miss a unit test failure.

There are rules for more elaborate testing: `compile`, `compile-fail`, `run` and `run-fail`. They are more suitable for automated testing, and are not covered here.

[6] see the definition of "free" in the section called “Feature Attributes”.