## Conditions and alternatives

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

    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. Also, whenever its release variant is built, `<define>EXTRA_FAST` will appear in its properties.

Sometimes the ways a target is built are 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

When building `demangler`, Boost.Build will compare requirements for each alternative with build properties to find the best match. For example, when building with with `<toolset>gcc` alternative 2, will be selected, and when building with `<toolset>msvc` alternative 3 will be selected. In all other cases, the most generic alternative 1 will be built.