Conditional targets not resolving properly

View: New views
7 Messages — Rating Filter:   Alert me  

Conditional targets not resolving properly

by Johan Larsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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

Obviously, I want the builds to match the closest possible alternative; that is, any build with a toolset other than gcc should match the first target, and any build with gcc as a toolset should match the second target.

Is there a way to achieve this, or perhaps a different way altoghether to exclude source files from a target when build with a particular toolset?

_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build

Re: Conditional targets not resolving properly

by Matthew Chambers-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Indirect conditionals are my preferred solution for this case.

rule exclude-source-if-not-gcc ( properties * )
{
   if ! <toolset>gcc in $(properties) { return <source>SOURCE.cpp ; }
}

project A
  : requirements
    <link>static
    <toolset>gcc:<cxxflags>-DNO_SMART
  : usage-requirements
    <linkflags>-lA
    <include>.
  ;

alias commonsources
  :  (snip)
  ;

lib libA
  : commonsources
  : <conditional>@exclude-source-if-not-gcc
  ;

HTH,
-Matt


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
>
> Obviously, I want the builds to match the closest possible
> alternative; that is, any build with a toolset other than gcc should
> match the first target, and any build with gcc as a toolset should
> match the second target.
>
> Is there a way to achieve this, or perhaps a different way altoghether
> to exclude source files from a target when build with a particular
> toolset?
> ------------------------------------------------------------------------
>
> _______________________________________________
> Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
>  
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build

Re: Conditional targets not resolving properly

by Phillip Seaver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
>
> Obviously, I want the builds to match the closest possible
> alternative; that is, any build with a toolset other than gcc should
> match the first target, and any build with gcc as a toolset should
> match the second target.
>
> Is there a way to achieve this, or perhaps a different way altoghether
> to exclude source files from a target when build with a particular
> toolset?

This should work:

    project A
      : requirements
        <link>static
        <toolset>gcc:<define>NO_SMART
      : usage-requirements
        <include>.
      ;

    lib libA
      : (snip)
      : <toolset>gcc:<source>SOURCE.cpp
      ;



The <source> feature adds that file to the list of sources as if you had
specified it in the same argument as "(snip)".

I got rid of the "<linkflags>-lA" because just referring to this project
in another project would cause it to link against libA and it kind of
defeats the purpose of using boost-build if you're using <linkflags> and
<cxxflags> when there's a feature that does the same thing in a
cross-platform way.  :-)

Phillip
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build

Re: Conditional targets not resolving properly

by Vladimir Prus :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build

Re: Conditional targets not resolving properly

by Johan Larsson-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



On Mon, Sep 14, 2009 at 11:01 AM, Vladimir Prus <ghost@...> 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

Re: Conditional targets not resolving properly

by Konstantin Litvinenko-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Johan Larsson пишет:

> 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
>   ;
>

   Try the following:
====================================
alias src : SOURCE.cpp ;
alias src : : <toolset>gcc ;
explicit src ;

lib libA
    :
      [ glob ../src/*.cpp ] # place here you common sources
      src
    :
     <link>static
     <toolset>gcc:<cxxflags>-DNO_SMART
    :
    :
     <include>..
    ;
==================================

You don't need to specify any link flags to link with libA, bjam can
handle this for you.

Notice: I've remove 'project' section.


_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build

Re: Conditional targets not resolving properly

by Phillip Seaver :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Johan Larsson wrote:

>
>
> On Mon, Sep 14, 2009 at 11:01 AM, Vladimir Prus <ghost@...
> <mailto:ghost@...>> 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
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build