boostconditional-statementsbjamboost-buildb2

How do you conditionally add a file to sources in boost.build?


build.jam:

project : usage-requirements <include>. ;

alias PUB : : : : <use>/ProjectA//PUB
                  <use>/ProjectB//PUB ;

lib LIB : [ glob *.c : feature.c ]
        : <link>static
          <use>/ProjectA//PUB
          <use>/ProjectB//PUB ;

I would like to add a target that will add feature.c to the sources and define USE_FEATURE. I've tried a few different things, but none seem to work as I want.

alias LIB_WITH_FEAT : LIB feature.c : <define>USE_FEATURE ;

alias LIB_WITH_FEAT : LIB : <source>feature.c <define>USE_FEATURE ;

does not add feature.c or USE_FEATURE to the build. But gives no errors or warnings. It just builds LIB.

lib LIB_WITH_FEAT : feature.c LIB : <define>USE_FEATURE ;

gives "warn: Unable to construct LIB_WITH_FEAT". Although if it worked, I don't think it'd be what I wanted as it would try to build LIB separately and LIB needs the USE_FEATURE to work properly with feature.c.


Solution

  • Your key problem is that <define> is a free feature. And as such doesn't cause differentiation in the variant of what to build. To do what you want you need to create a new feature that describes what build option you are selecting (see feature documentation). For example:

    import feature : feature ;
    feature with-feat : no yes : optional propagated ;
    

    You can then define whatever you want on your targets based on that feature's value. For example to define symbols or add sources:

    lib LIB
        : [ glob *.c : feature.c ]
        : <link>static
          <use>/ProjectA//PUB
          <use>/ProjectB//PUB
          <with-feat>yes:<define>USE_FEATURE
          <with-feat>yes:<source>feature.c
        ;
    

    Or you can use the conditional rule shorthand if you have many extra requirements to add:

    lib LIB
        : [ glob *.c : feature.c ]
        : <link>static
          <use>/ProjectA//PUB
          <use>/ProjectB//PUB
          [ conditional <with-feat>yes :
            <define>USE_FEATURE
            <source>feature.c ]
        ;
    

    To select a particular variation of that LIB from another target you specify the feature requirement in the target reference:

    exe my-feat-exe : source.cpp LIB/<with-feat>yes ;