Boost logo

Boost-Build :

Subject: Re: [Boost-build] One more issue with <embed-manifest> feature.
From: Vladimir Prus (ghost_at_[hidden])
Date: 2009-02-03 04:21:12


[sending to list now]

On Monday 02 February 2009 10:09:56 you wrote:
> > Now the problem is if the code above is executed twice two
> > file-targets will be created by [ class.new file-target ... ] but only
> > one of them will be returned. virtual-target.register checks it has
> > seen a particular target already and if so it will return the first
> > instance of the target to the caller.
>
> Sorry, I phrased it in a way that nobody would be able understand. :-(
> Let me try again.
>
> Each invocation of "msvc-linking-generator.generated-targets" creates
> an instance of file-target object that represents generated MANIFEST
> file. This target is registered in three places:
>
> 1. With the associated action in abstract-file-target constructor:
>
> $(action).add-targets $(__name__) ;
>
> 2. By calling "virtual-target.register"
> 3. The instance of the target is included to the list of targets
> returned by generated-targets and participate in building of
> dependency tree.
>
> So the problem is that #1 registers every created instance of
> file-target while #2 ignores a target if it was seen previously. When
> "msvc-linking-generator.generated-targets" is called twice for the
> same target (and with the same properties) the second instance of
> MANIFEST file-target will be abandoned because
> "virtual-target.register" thinks it is identical to the 1st one. But
> it will not gone completely because it was already registered via #1.
> This causes "duplicate target" errors later in the build process
> during actions actualization phase.
>
> Hope this is somehow better explanation. :-)

It appears that the trick used in manifest case is broken. Usually,
the fact that a target is registered in (1) does not matter because
the target that uses that action goes via virtual-target.register
later.

Here, we have a target (EXE) that already went via virtual-target.register,
we take its action, and add a new target to that action. And then, passing
the extra target via virtual-target.register breaks things. I think the
most straight-forward solution would be a new method for action class
that replaces a target with another. So, the code would be:

        local t = [ class.new file-target $(name) : MANIFEST : $(project) : $(action) ] ;
        local tr = [ virtual-target.register $(t) ] ;
        $(action).replace-target $(t) : $(tr) ;

What do you think?

- Volodya


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