Boost logo

Boost-Build :

Subject: Re: [Boost-build] Conditional targets not resolving properly
From: Phillip Seaver (phil_at_[hidden])
Date: 2009-09-16 11:08:38


Johan Larsson wrote:
>
>
> On Mon, Sep 14, 2009 at 11:01 AM, Vladimir Prus <ghost_at_[hidden]
> <mailto:ghost_at_[hidden]>> wrote:
>
> On Thursday 10 September 2009 Johan Larsson wrote:
>
> > Hello.
> >
> > As part of a project, I have a library with an associated
> Jamfile I need to
> > build. I want to build this particular library as a static lib,
> so I've
> > added <link>static to the project requirements in the Jamfile
> for the
> > library. So far so good.
> >
> > However, I also want to exclude a particular source file from
> the library if
> > I use a particular toolset (gcc in this case). So I've created
> two targets;
> > one with all the sources and no particular requirements, and one
> without the
> > source file in question with <toolset>gcc added as a
> requirement, like so:
> >
> >
> >
> > project A
> > : requirements
> > <link>static
> > <toolset>gcc:<cxxflags>-DNO_SMART
> > : usage-requirements
> > <linkflags>-lA
> > <include>.
> > ;
> >
> > alias commonsources
> > : (snip)
> > ;
> >
> > lib libA
> > : commonsources
> > SOURCE.cpp
> > ;
> >
> > lib libA
> > : commonsources
> > : <toolset>gcc
> > ;
> >
> > The problem is that when building with a toolset that is not
> gcc, bjam fails
> > to find an appropriate target. The output it gives me is as follows:
> > error: No best alternative for ./libA
> > next alternative: required properties: <link>static
> > not matched
> > next alternative: required properties: <link>static <toolset>gcc
> > not matched
>
> Johan,
>
> you are running into a known issue:
>
> https://zigzag.lvk.cs.msu.su:7813/boost.build/ticket/16
>
> Can you let me know if the workarounds suggested by Matthew and
> Phillip
> work for you?
>
> Thanks,
> Volodya
>
>
> They both work - and thank you to both Matthew and Phillip. However,
> both workarounds have issues:
>
> Matthew's solution produces the desired behaviour to the letter, but
> I've found no way to specify which sources to add or exclude in the
> conditional rule except by hardcoding them into the rule itself. This
> means that if a user wants to produce this kind of behaviour, they
> have to write a specific rule for each Jamfile where this behaviour is
> needed. Not very practical.
>
> Phillip's solution is more elegant, but does not produce strictly the
> behaviour I need. Specifically, I need to exclude a source file if a
> specific toolset is used. This means I need to be able to either
> specify a negative condition (such as <toolset> ! gcc or similar) or
> specify a remove source rule (<removesource>SOURCE.cpp or similar),
> neither of which I've been able to do. So instead, I'll have to
> specify each positive case explicitly (<toolset>gcc:...
> <toolset>co:... <toolset>intel:...) which is obviously not very
> maintainable.
>
> So in the end, they both can be used, but not without issues. The
> solution proposed in the ticket you linked would be a very, very
> welcome addition, should it ever get fixed.
> ------------------------------------------------------------------------
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
>

In case there's no solution at the moment, here's a work-around I came
up with. If you add it to a jamfile, you can see what it does.

    import feature ;
    import set ;

    # this gets the configured toolsets
    local toolsets = [ feature.values <toolset> ] ;
    ECHO "toolsets =" $(toolsets) ;

    # this just sets it to a list so you can see what the results are
    # you wouldn't actually use this code
    toolsets = msvc gcc co intel ;
    ECHO "toolsets =" $(toolsets) ;

    # this removes "gcc" from the list
    toolsets = [ set.difference $(toolsets) : gcc ] ;
    ECHO "toolsets =" $(toolsets) ;

    ECHO "requirement =" <toolset>$(toolsets):<source>SOURCE.cpp ;

In your case you could do something like:

    import feature ;
    import set ;

    local not-gcc = [ set.difference [ feature.values <toolset> ] : gcc ] ;
    lib libA
          : (snip)
          : <toolset>$(not-gcc):<source>SOURCE.cpp
          ;

Phillip


Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk