List Info

Thread: Problem with ambiguity error




Problem with ambiguity error
user name
2006-02-28 08:25:34
On Monday 27 February 2006 00:14, Daniel Einspanjer wrote:
> "Vladimir Prus" <ghostcs.msu.su> wrote in message
> news:200602261936.16703.ghostcs.msu.su...
>
> > no, I'm afraid no idea yet. Any chance you can
provide a testcase which
> > reproduces the problem? Then I might be able to
get to the root of the
> > problem much faster then if we exchange the
necessary information over
> > email.
> >
> > BTW, it's always preferrable to include testcases
together with bug
> > reports/queries, as they tend to be more accurate
than extracts from
> > code.
>
> Sorry to make things more difficult for you. I thought
it would be better
> to just include a snippet of code at first because I
was afraid I might
> just have some glaring syntax error that would be
obvious.
>
> Attached is a testcase that demonstrates the ambiguity
error.  Just run
> bjam on the extracted directory.

Thank you, this reproduces. 

Here's what's going on. First of all, to clarify your
intent, I suggest you 
make all generators that now produce CPP type produce
CUSTOMERINFO type. 
Likewise, instead of 

    cpp csconfig-customer.cpp

you better write

    customerinfo csconfig-customer.cpp

as you're really producing customer info file, not some
random CPP. With those 
change you get this pair of generators:

      csconfig.transform: CSCONFIG -> CUSTOMERINFO
      customerinfo.transform: CUSTOMERINFO ->
CUSTOMERINFO

For a simplified use case:

    cpp csconfig-customer.cpp
       : # sources
          csconfig-base.ini
      ;

you really get two possible transformation chains:

   CSCONFIG -> CUSTOMERINFO
   CSCONFIG -> CUSTOMERINFO -> CUSTOMERINFO

In theory, the CUSTOMERINFO -> CUSTOMERINFO step can be
applied N times more, 
but Boost.Build does not allow repating application of the
same generator for 
obvious reasons.

The most likely situation is that you want the CUSTOMERINFO
-> CUSTOMERINFO 
generator to be only invoked when you explicitly ask for
this.

1. If the generator should be invoked only when some
property, say <customer> 
is in build properties, use this:

  generators.override csconfig.transform :
customerinfo.transform ;
  
  generators.register [ new customerinfo-generator
customerinfo.transform :
       CUSTOMERINFO : CUSTOMERINFO : <customer> ] ;

This way, the customerinfo.transform generator won't be
used unless there's 
<customer> in the properties. Or you can use:

  generators.register [ new customerinfo-generator
customerinfo.transform :
       CUSTOMERINFO : CUSTOMERINFO :
<allow>customerinfo.transform ] ;

and add <allow>customerinfo.transform to requirements
if you want this 
generator to run. The <allow> property is the standard
one. You can use a 
helper rule to automatically add this property when
declaring targets:

   rule customerinfo-transformed ( name : sources * :
requirements * .. )
   {
        customerinfo $(name) 
           : $(sources) 
           : $(requirements)
<allow>customerinfo.transform 
           .........
   }

2. You can change customerinfo.transform signature:

   type.register CUSTOMERINFO_TRANSFORMED : : CUSTOMERINFO ;
   generators.register [ new customerinfo-generator
customerinfo.transform :
       CUSTOMERINFO : CUSTOMERINFO :
<allow>customerinfo.transform ] ;

and again use 'customerinfo-transformed' rule when you
need to transform 
customer info.

In both cases, you won't need the 'cast' rule to indicate
you need to 
transform, as you try to do in the first target in Jamroot
you've sent.

I'd prefer method 2 above, as it's the most
straight-forward.

And as a closing remark, the explanation why you get the
error with the 
current code, where target type of generators is CPP.
Here's the second 
transformation chains that Boost.Build finds:

    1. customerinfo.transform has CPP as target type so
it's asked
       to create CPP from CSCONFIG 
    2. Source type of customerinfo.transform is
CUSTOMERINFO. There are
       no generators for this type. 
    3. Boost.Build tries generators for base types of
CUSTOMERINFO, in this
       case -- CPP.
    4. It finds the csconfig.transform (CSCONFIG->CPP)
generator.

If Boost.Build did not do (3), this chain would not be
found, and you'd have 
no ambiguity. However, this will prevent a handy feature --
you can create a 
new target type derived from an existing one and change
it's extension, but 
all the generators will be inherited. Say, if you do:

  type.register MY_PLUGIN : plg : SHARED_LIB ;

you've be able to build .plg files on all platforms using
standard dll linking 
actions.

So, I'd suggest using one of two methods I've suggested,
as they'll solve the 
problem and make the code more explicit.

HTH,
Volodya
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )