## Declaring Targets

A Main target is a user-defined named entity that can be built, for example an executable file. Declaring a main target is usually done using one of the main target rules described in the section called “Builtin rules”. The user can also declare custom main target rules as shown in the section called “Main target rules”.

Most main target rules in Boost.Build have the same common signature:

    rule rule-name (
         main-target-name :
         sources + :
         requirements * :
         default-build * :
         usage-requirements * )

- `main-target-name` is the name used to request the target on command line and to use it from other main targets. A main target name may contain alphanumeric characters, dashes (‘`-`’), and underscores (‘`_`’).
- `sources` is the list of source files and other main targets that must be combined.
- `requirements` is the list of properties that must always be present when this main target is built.
- `default-build` is the list of properties that will be used unless some other value of the same feature is already specified, e.g. on the command line or by propagation from a dependent target.
- `usage-requirements` is the list of properties that will be propagated to all main targets that use this one, i.e. to all its dependents.

Some main target rules have a different list of parameters as explicitly stated in their documentation.

The actual requirements for a target are obtained by refining requirements of the project where a target is declared with the explicitly specified requirements. The same is true for usage-requirements. More details can be found in the section called “Property refinement”

### Name

The name of main target has two purposes. First, it's used to refer to this target from other targets and from command line. Second, it's used to compute the names of the generated files. Typically, filenames are obtained from main target name by appending system-dependent suffixes and prefixes.

The name of a main target can contain alphanumeric characters, dashes, undescores and dots. The entire name is significant when resolving references from other targets. For determining filenames, only the part before the first dot is taken. For example:

    obj test.release : test.cpp : <variant>release ;
    obj test.debug : test.cpp : <variant>debug ;

will generate two files named `test.obj` (in two different directories), not two files named `test.release.obj` and `test.debug.obj`.

### Sources

The list of sources specifies what should be processed to get the resulting targets. Most of the time, it's just a list of files. Sometimes, you'll want to automatically construct the list of source files rather than having to spell it out manually, in which case you can use the `glob` rule. Here are two examples:

    exe a : a.cpp ;           # a.cpp is the only source file
    exe b : [ glob *.cpp ] ;  # all .cpp files in this directory are sources

Unless you specify a file with an absolute path, the name is considered relative to the source directory — which is typically the directory where the Jamfile is located, but can be changed as described in the section called “Projects”.

The list of sources can also refer to other main targets. Targets in the same project can be referred to by name, while targets in other projects must be qualified with a directory or a symbolic project name. The directory/project name is separated from the target name by a double forward slash. There's no special syntax to distinguish the directory name from the project name—the part before the double slash is first looked up as project name, and then as directory name. For example:

    lib helper : helper.cpp ;
    exe a : a.cpp helper ;
    # Since all project ids start with slash, ".." is directory name.
    exe b : b.cpp ..//utils ;
    exe c : c.cpp /boost/program_options//program_options ;

The first exe uses the library defined in the same project. The second one uses some target (most likely library) defined by Jamfile one level higher. Finally, the third target uses some C++ Boost library, referring to it by absolute symbolic name. More information about target references can be found in the section called “Dependent Targets” and the section called “Target identifiers and references”.

### Requirements

Requirements are the properties that should always be present when building a target. Typically, they are includes and defines:

    exe hello : hello.cpp : <include>/opt/boost <define>MY_DEBUG ;

There is a number of other features, listed in the section called “Builtin features”. For example if a library can only be built statically, or a file can't be compiled with optimization due to a compiler bug, one can use

    lib util : util.cpp : <link>static ;
    obj main : main.cpp : <optimization>off ;

Sometimes, particular relationships need to be maintained among a target's build properties. This can be achieved with conditional requirements. For example, you might want to set specific `#defines` when a library is built as shared, or when a target's `release` variant is built in release mode.

    lib network : network.cpp
        : <link>shared:<define>NEWORK_LIB_SHARED
         <variant>release:<define>EXTRA_FAST
        ;

In the example above, whenever `network` is built with `<link>shared`, `<define>NEWORK_LIB_SHARED` will be in its properties, too.

You can use several properties in the condition, for example:

    lib network : network.cpp
        : <toolset>gcc,<optimization>speed:<define>USE_INLINE_ASSEMBLER
        ;

A more powerful variant of conditional requirements is indirect conditional requirements. You can provide a rule that will be called with the current build properties and can compute additional properties to be added. For example:

    lib network : network.cpp
        : <conditional>@my-rule
        ;
    rule my-rule ( properties * )
    {
        local result ;
        if <toolset>gcc <optimization>speed in $(properties)
        {
            result += <define>USE_INLINE_ASSEMBLER ;
        }
        return $(result) ;
    }

This example is equivalent to the previous one, but for complex cases, indirect conditional requirements can be easier to write and understand.

Requirements explicitly specified for a target are usually combined with the requirements specified for the containing project. You can cause a target to completely ignore specific project's requirement using the syntax by adding a minus sign before a property, for example:

    exe main : main.cpp : -<define>UNNECESSARY_DEFINE ;

This syntax is the only way to ignore free properties from a parent, such as defines. It can be also useful for ordinary properties. Consider this example:

    project test : requirements <threading;>multi ;
    exe test1 : test1.cpp ;
    exe test2 : test2.cpp : <threading;>single ;
    exe test3 : test3.cpp : -<threading;>multi ;

Here, `test1` inherits project requirements and will always be built in multi-threaded mode. The `test2` target overrides project's requirements and will always be built in single-threaded mode. In contrast, the `test3` target removes a property from project requirements and will be built either in single-threaded or multi-threaded mode depending on which variant is requested by the user.

Note that the removal of requirements is completely textual: you need to specify exactly the same property to remove it.

### Default Build

The `default-build` parameter is a set of properties to be used if the build request does not otherwise specify a value for features in the set. For example:

    exe hello : hello.cpp : : <threading>multi ;

would build a multi-threaded target unless the user explicitly requests a single-threaded version. The difference between requirements and default-build is that requirements cannot be overridden in any way.

### Additional Information

The ways a target is built can be so different that describing them using conditional requirements would be hard. For example, imagine that a library actually uses different source files depending on the toolset used to build it. We can express this situation using target alternatives:

    lib demangler : dummy_demangler.cpp ;                      # alternative 1
    lib demangler : demangler_gcc.cpp : <toolset>gcc ;   # alternative 2
    lib demangler : demangler_msvc.cpp : <toolset>msvc ; # alternative 3

In the example above, when built with `gcc` or `msvc`, `demangler` will use a source file specific to the toolset. Otherwise, it will use a generic source file, `dummy_demangler.cpp`.

It is possible to declare a target inline, i.e. the "sources" parameter may include calls to other main rules. For example:

    exe hello : hello.cpp
        [ obj helpers : helpers.cpp : <optimization>off ] ;

Will cause "helpers.cpp" to be always compiled without optimization. When referring to an inline main target, its declared name must be prefixed by its parent target's name and two dots. In the example above, to build only helpers, one should run `bjam hello..helpers`.

When no target is requested on the command line, all targets in the current project will be built. If a target should be built only by explicit request, this can be expressed by the `explicit` rule:

    explicit install_programs ;