CreateItem vs ItemGroup

只谈情不闲聊 提交于 2020-01-20 16:53:28

问题


What is the difference between creating an item inside a target like this:

<Target Name="DoStuff">
    <CreateItem Include="@(IntermediateAssembly)" >
        <Output TaskParameter="Include" ItemName="FileWrites"/>
    </CreateItem>
</Target>

and like this:

<Target Name="DoStuff">
    <ItemGroup>
        <FileWrites Include="@(IntermediateAssembly)" />
    </ItemGroup>
</Target>

When would you use one or the other and why?


回答1:


In versions of MSBuild prior to 3.5 you could not define properties or items inside of targets (like in your second example). So a task was used instead (CreateItem and CreateProperty)

If you are using ToolsVersion 3.5 then you don't need to use CreateItem anymore (though you still can if you prefer).

In the end they both create the item the same, with the same scope. Using the second syntax is more readable and setting up custom meta data is much easier (in my opinion).

NOTE: The 3.5 version of MSBuild is installed with .NET 3.5. Though you need to define ToolsVersion="3.5" in the Project tag of your MSBuild file to use 3.5 features.

In case you are wondering, I got most of this info from the book Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build which I really liked (but am not affiliated with in any way).




回答2:


CreateItem and CreateProperty are obsoleted in MSBuild 3.5 (though will always continue to work, of course). It was pretty obvious we needed the same familiar syntax for ItemGroup and PropertyGroup to work inside targets.

But ItemGroup inside a target has some special extra powers. It can modify items: for example, this will add true to all items in Resources list that have a metadata named Primary with value of true; only if there isn't already Copy metadata:

<ItemGroup>
  <Resources Condition=" '%(Primary)' == 'true' ">
    <Copy Condition=" '%(Copy)' == '' ">true</Copy>
  </Resources>
</ItemGroup>

One other magic power: you can now remove items from a list. This example will remove all items from the Resources list that have metadata Type with value Bitmap:

<ItemGroup>
  <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/>
</ItemGroup>

These magic powers only work inside at present, not outside.

For full details of this stuff, I highly recommend Sayed Hashimi's book on MSBuild. It's easily found on Amazon.

Dan -- msbuild team.




回答3:


I dont think the answer accepted has defined the difference.

The difference is:

  • ItemGroup is evaluated when the MSBuild script is loaded.
  • CreateItem is evaluated when the Target is executed

This can lead to different values of the Item within the script.

Take the example of a Task that does something with a all the files that match "*.txt" in a directory. If your MSBuild script is loaded in visual studio, only the files that existed when VS started will be in the Item if you use ItemGroup.

If you use CreateItem - it will do a search for all *.txt files when the target is executed.




回答4:


As an additional info for others passing here: The Build-Engine that contains an API to construct MSBuild projects does not support adding ItemGroups the new way to a Target. Here you WILL have to use the old-fashioned way.



来源:https://stackoverflow.com/questions/937681/createitem-vs-itemgroup

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!