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
Anonymous
January 03, 2006
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" 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 eitherAnonymous
January 07, 2006
Here is a workaround for both
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" 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.Anonymous
January 12, 2006
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.Anonymous
June 01, 2006
Best of the text i read about a problem.Anonymous
June 08, 2006
Hi! http://www.insurance-top.com/company/ auto site insurance. car site insurance, The autos insurance company, compare car insurance. from website .Anonymous
June 10, 2006
Hi! http://www.ringtones-dir.com/get/ ringtones site. Download ringtones FREE, Best free samsung ringtones, Cingular ringtones and more. From website .Anonymous
September 21, 2006
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!Anonymous
February 17, 2008
The comment has been removedAnonymous
January 06, 2010
Did this ever get fixed? I just run straight into it trying to create a master build script. This is a really bad bug!Anonymous
February 07, 2010
The comment has been removedAnonymous
March 24, 2010
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.