Boost logo

Boost-Build :

Subject: Re: [Boost-build] One more issue with <embed-manifest> feature.
From: Alexey Pakhunov (alexeypa_at_[hidden])
Date: 2009-02-02 02:09:56


> 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. :-)

On Sun, Feb 1, 2009 at 10:32 PM, Alexey Pakhunov <alexeypa_at_[hidden]> wrote:
> Hi,
>
> There is another problem with <embed-manifest> feature. Currently
> msvc-linking-generator.generated-targets uses the following code to
> create file-target for generated manifest:
>
> result += [ virtual-target.register
> [ class.new file-target $(name) : MANIFEST :
> $(project) : $(action) ] ] ;
>
> Note that when $(action) is specified (which is normally the case) the
> constructor of abstract-file-target will register the newly register
> target with that action:
>
> self.action = $(action) ;
> if $(action)
> {
> $(action).add-targets $(__name__) ;
>
> if $(self.type) && ! $(exact)
> {
> _adjust-name $(name) ;
> }
> }
>
> 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.
>
> The setup I can see it is a bit complex and I'm trying to reduce it to
> a meaningful repro. But basically it is:
>
> # file 1
> exe build_tool : ... ;
>
> # file 2
> class build_tool_generator
> {
> rule run ( ... )
> {
> # run is looking for build_tool target and:
> # 1. set is a dependency to the target this generator builds
> # 2. save binary path in a custom feature for later use
> # see quickbook.jam for example.
> }
> }
>
> generators.register [ new build_tool_generator : FOO : BAR ] ;
>
> # file 3
> bar baz : source.foo ;
>
> exe rabbit : ... : <dependency>baz ;
>
> # file 4
> install dist : rabbit ;
>
> build_tool_generator is used to build build_tool and use it for
> converting .foo to .bar. When I build "dist" I see that
> msvc-linking-generator.generated-targets is cassed twice for
> build_tool.
>
> At this point I'm not sure what is exactly the problem: unconditional
> registration of file-target with their actions or multiple invocations
> of generated-targets rule. But I hope that Vladimir can cast some
> light on this problem. :-)
>
> --
> Best regards,
> Alexey Pakhunov.
>

-- 
Best regards,
  Alexey Pakhunov.

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