Msbuild 如何在目标之间传递带有元数据的ItemGroup?
根据我的理解,使用Msbuild 如何在目标之间传递带有元数据的ItemGroup?,msbuild,Msbuild,根据我的理解,使用DependsOnTargets在目标之间传递ItemGroup是必要的。我不确定是否有其他方法可以在不依赖目标的情况下通过目标 我已测试ItemGroup无法从CallTarget或MSBuild任务传递。解决方案是将项目组转换为属性(展平),并使用Properties传递 我定义了文件的项目组。文件具有值元数据。我想为每个递归循环执行target并删除一个文件项。这是我的剧本: <Target Name="MyGroup"> <ItemGroup>
DependsOnTargets
在目标之间传递ItemGroup是必要的。我不确定是否有其他方法可以在不依赖目标的情况下通过目标
我已测试ItemGroup无法从CallTarget
或MSBuild
任务传递。解决方案是将项目组转换为属性(展平),并使用Properties
传递
我定义了文件
的项目组
。文件
具有值
元数据。我想为每个递归循环执行target并删除一个文件
项。这是我的剧本:
<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: 3a;2a;1a Value=3
File: 2a;1a Value=2
File: 1a Value=1
File: Value=0
有解决方案吗?不太可能,您试图绕过msbuild的思想,只构建一次目标(除非输入\输出发生更改)。 并且不能在MSBuild上下文之间传递项组(当调用MSBuild任务时,将创建新上下文)。此外,在脚本中,ItemGroup的作用域为target,您需要全局定义它,以便其他目标可以使用它。 您可以做的是:
- 定义全局属性值,条件是使用传递给脚本的属性值(如果存在)
- 将ItemGroup从MyGroup目标更改为全局范围
- 根据value属性的值定义要发出的itemgroup的每个元素的条件
<?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>
谢谢但是我无法在实际项目中使用
条件属性构建ItemGroup。给出的示例是一个原型,展示了我面临的问题。这些项是我的项目中的一组文件。MSBuild脚本实际上不是“用于生成项目的过程语言”,因此,如果您对项目组没有控制权或几乎没有控制权,则问题的答案是“否”(至少是afaik)—MSBuild将处理所有全局属性和项,然后再向这些属性和项添加任何目标调用和项,但是没有被移除。你能描述一下你想要实现什么吗?也许有另一种解决方案不需要递归调用?编辑:嗯,对不起,我没注意到你的答案。我很高兴你用另一种方法解决了你的问题我的问题是我有一组Delphi
project(290++)要构建。这些项目之间存在依赖关系。我已经成功地从这些项目中构建了依赖关系,并使用项目元数据将其保存在ItemGroup
中,以保存依赖信息。首先,我从ItemGroup
中筛选一个没有依赖关系的项目列表,并以并行方式执行构建任务。然后,我从ItemGroup中删除新构建对象文件的依赖关系。在第二个循环中,我再次过滤。这些操作将使用MSBuild
以递归方式执行。您是否使用MSBuild构建Delphi项目,例如,在exec中调用您自己的编译器?为什么要使用MSBuild而不是任何其他脚本语言?我不确定您为什么选择MSBuild,但我想说,对于.NET以外的任何对象,它作为批处理构建语言都是平庸的。它对于.NET构建非常有用,因为所有的构建过程都与之相关。您在.NET中的问题可能会很容易解决—只需构建输出项目,所有依赖项都将自动生成。Delphi
自2007年起使用MSBuild
来构建一组项目(groupproj
和dproj
文件)。更多信息:
<?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>
<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>