Builtin target types

| 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 which 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 which should be passed to the `-l` option, and the `file` property specifies the file location. The `search` feature specifies paths where the library should be searched. That feature can be specified several time, or 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` 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 giu : : <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`), which 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 which link to `a` will also link to `b`.

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

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

then compiler include path for all targets which use `helpers` will contain the directory where the target is defined.path to "helpers.cpp". So, the user need only to add `helpers` to the list of sources, and don't bother about other requirements. This allows to greatly simplify Jamfiles.

### Note

If you don't want shared libraries to include all libraries which 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 which 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 the 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 boost_thread : /boost/thread//boost_thread : <link>static ;

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

It is also allowed to 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 the built target you should use the `stage` rule follows the common syntax. For example:

    stage dist : hello helpers ;

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

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

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

    stage dist : hello
               : <traverse-dependencies>on <include-type>EXE
                 <include-type>LIB
               ;

will find all targets that `hello` depends on, and install all of the which are either executables or libraries.

### 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 error, the build system will also return 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 yet.