Well Known Limitation: Dynamic items and properties not emitted until target execution completes


Sayed Ibrahim Hashimi has written about a restriction that he ran into when using CreateProperty and CreateItem tasks to dynamically emit properties and items.  The issue has to do with not being able to access items and properties that are created within a target until the target execution actually completes.


So, if you were to run CreateProperty or CreateItem and immediately execute the CallTarget task to invoke another target that needed access either an item or property that was just created, you will be out of luck.  We don’t publish dynamic properties or items until the target that created them is done executing.  This is a known issue for Whidbey.  Fortunately the workaround is simple:  have one target emit the items/properties and finish execution before you run the next target that uses them.  You can sequence the execution of these two targets via a DependsOnTargets attribute on a master target – alternatively the master target can use CallTarget to invoke both the targets sequentially.


Thank you Sayed for reporting it via the MSDN Product Feedback Center.  We have it on our list of feature items to consider for Orcas, and we will need to either publish items and properties globally even before the target execution completes – or alternatively allow parameter passing into targets.


Feedback and blogging about these topics just gives us a better idea of the pain points our customers are experiencing today.  Thanks for the feedback and continue sending us more.


[ Author: Faisal Mohamood ]

Comments (11)

  1. Scott Ferrett says:

    Unfortunately the workaround does not work because of another bug in MSBuild. You cannot use CallTarget to call a target more than once in a Task. Try this example:

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003&quot; DefaultTarget="Build">

    <ItemGroup>

    <List1 Include = "*.*"/>

    </ItemGroup>

    <ItemGroup>

    <List2 Include = "c:*.*"/>

    </ItemGroup>

    <Target Name = "DoMessage">

    <Message Text = "@(MessageList)" />

    </Target>

    <Target Name = "Set1">

    <CreateItem Include= "@(List1)">

    <Output TaskParameter = "Include" ItemName = "MessageList" />

    </CreateItem>

    </Target>

    <Target Name = "Set2">

    <CreateItem Include= "@(List2)">

    <Output TaskParameter = "Include" ItemName = "MessageList" />

    </CreateItem>

    </Target>

    <Target Name = "Build">

    <CallTarget Targets = "Set2;DoMessage"/>

    <CallTarget Targets = "Set1;DoMessage"/>

    </Target>

    </Project>

    Doing

    <CallTarget Targets = "Set2;DoMessage;Set1;DoMessage>

    Does not help either

  2. Here is a workaround for both

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003&quot; DefaultTargets="Create">

    <Target Name="Create">

    <CreateProperty Value="E:Data">

    <Output TaskParameter="Value" PropertyName="DestFolder" />

    </CreateProperty>

    <CreateItem Include="*.*">

    <Output TaskParameter="Include" ItemName="TestFiles"/>

    </CreateItem>

    <CallTarget Targets="Print"/>

    <MSBuild

    Projects="$(MSBuildProjectFile)"

    Targets="Print"

    Properties="DestFolder=$(DestFolder)"

    />

    </Target>

    <Target Name="Print">

    <Message Text="Print target called"/>

    <Message Text="Dest: $(DestFolder)"/>

    <Message Text="TestFiles: @(TestFiles)"/>

    </Target>

    </Project>

    We can use the MSBuild task to fix both issues, first we use CallTarget to call the Print target. Then call the MSBuild target on it again, this time passing in the required properties. This bypasses incremental building (the reason why Print only gets executed once), but has many limitations, namely you can’t pass in items and you must specify which properties that need to get passed. I imagine if you are creative you can find ways to fix this issue as well, but maybe seem like a lot of work. Let us know if this works for you or not.

    This has also been posted to the MSDN Product feedback center.

  3. Scott Ferrett says:

    I ended up using a completely different approach to using CallTarget.

    I did not realise that CreateItem as incremental. I thought that CreateItem created an item list, but it actually appends to an existing list. So instead of calling a task multiple times, I just put everything I wanted to do into an item list with extra meta data using CreateItem and then executed the necessary task once passing the new item list

    It would be nice if the documentation for CreateItem was updated with an example that shows that calling it multiple times on the same Item will append information, not replace.

  4. rape stories says:

    Best of the text i read about a problem.

  5. Hi! http://www.insurance-top.com/company/ auto site insurance. car site insurance, The autos insurance company, compare car insurance. from website .

  6. Hi! http://www.ringtones-dir.com/get/ ringtones site. Download ringtones FREE, Best free samsung ringtones, Cingular ringtones and more. From website .

  7. Stefan says:

    All this sounds unncessarily complicated just to pass a parameter into a target.

    "…or alternatively allow parameter passing into targets". What? That should have been part of MSBuild right from the beginning!

  8. Photo by: mistyeiz A couple of weeks ago I had one hell of a time with an MSBuild script. I felt like

  9. Did this ever get fixed? I just run straight into it trying to create a master build script. This is a really bad bug!

  10. ab says:

    This is just f&*^&*^ stupid.

    Have you guys ever used or seen any serious build project?

    Seroiusly, switching to NANT now, enough of this bullshit waisting time on half cooked amature tools. not happy

  11. Brian says:

    Anyone know if this is fixed with TFS 2010?  We’re seeing the same issue with TFS 2008.  And I agree this is totally stupid.  Microsoft needs to fix this asap.