根据我的理解,使用DependsOnTargets
是在目标之间传递ItemGroup所必需的。我不确定是否有其他方法可以在没有DependsOnTargets
的情况下传递目标。
我测试过ItemGroup无法从CallTarget
或MSBuild
任务传递。解决方法是将ItemGroup转换为property(展平它)并使用Properties
进行传递。
我定义了ItemGroup
File
。 File
具有Value
元数据。我想执行target并为每个递归循环删除一个File
项。这是我的剧本:
<Target Name="MyGroup">
<ItemGroup>
<File Include="5">
<Value>5a</Value>
</File>
<File Include="4">
<Value>4a</Value>
</File>
<File Include="3">
<Value>3a</Value>
</File>
<File Include="2">
<Value>2a</Value>
</File>
<File Include="1">
<Value>1a</Value>
</File>
</ItemGroup>
</Target>
<Target Name="Recursive" DependsOnTargets="MyGroup" Condition="$(Value) > 0">
<ItemGroup>
<File Remove="$(Value)" />
</ItemGroup>
<PropertyGroup>
<Value>$([MSBuild]::Subtract($(Value), 1))</Value>
</PropertyGroup>
<Message Text="File: @(File->'%(Value)') Value=$(Value)" Importance="High" />
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=$(Value)"/>
</Target>
<Target Name="Build" DependsOnTargets="MyGroup">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=5" />
</Target>
输出结果为:
File: 4a;3a;2a;1a Value=4
File: 5a;3a;2a;1a Value=3
File: 5a;4a;2a;1a Value=2
File: 5a;4a;3a;1a Value=1
File: 5a;4a;3a;2a Value=0
我希望输出为:
File: 4a;3a;2a;1a Value=4
File: 3a;2a;1a Value=3
File: 2a;1a Value=2
File: 1a Value=1
File: Value=0
有解决方案吗?
答案 0 :(得分:1)
不是真的,你试图绕过msbuild只想构建一次目标的想法(除非输入\输出发生变化)。 并且您无法在MSBuild上下文之间传递项目组(当您调用MSBuild任务时 - 创建新上下文)。同样在您的脚本中 - ItemGroup的作用域为目标 - 您需要全局定义它,以便其他目标可用。 你能做的是:
e.g。你的脚本将是这样的:
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Value Condition="$(Value) == ''">5</Value>
</PropertyGroup>
<ItemGroup>
<File Include="5" Condition="$(Value) >5">
<Value>5a</Value>
</File>
<File Include="4" Condition="$(Value) >4">
<Value>4a</Value>
</File>
<File Include="3" Condition="$(Value) >3">
<Value>3a</Value>
</File>
<File Include="2" Condition="$(Value) >2">
<Value>2a</Value>
</File>
<File Include="1" Condition="$(Value) >1">
<Value>1a</Value>
</File>
</ItemGroup>
<Target Name="Recursive" Condition="$(Value) >0">
<PropertyGroup>
<Value>$([MSBuild]::Subtract($(Value), 1))</Value>
</PropertyGroup>
<Message Text="File: @(File->'%(Value)') Value=$(Value)" Importance="High" />
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=$(Value)"/>
</Target>
<Target Name="Build">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=5" />
</Target>
</Project>
正如Alexey Shcherbak指出的那样,我们无法从ItemGroup
任务中通过MSBuild
。我通过引入新属性Done
来解决我的问题,以保留已处理的项目列表。
<Target Name="MyGroup">
<ItemGroup>
<File Include="5">
<Value>5a</Value>
</File>
<File Include="4">
<Value>4a</Value>
</File>
<File Include="3">
<Value>3a</Value>
</File>
<File Include="2">
<Value>2a</Value>
</File>
<File Include="1">
<Value>1a</Value>
</File>
</ItemGroup>
</Target>
<Target Name="Recursive" DependsOnTargets="MyGroup" Condition="$(Value) > 0" >
<ItemGroup>
<File Remove="$(Value)" />
<File Remove="$(Done)" />
</ItemGroup>
<Message Text="File: @(File->'%(Value)') Value=$(Value)" Importance="High" />
<PropertyGroup>
<Done>$(Done);$(Value)</Done>
<Value>$([MSBuild]::Subtract($(Value), 1))</Value>
</PropertyGroup>
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=$(Value);Done=$(Done)" />
</Target>
<Target Name="Build" DependsOnTargets="MyGroup">
<MSBuild Projects="$(MSBuildProjectFile)" Targets="Recursive" Properties="Value=5" />
</Target>