我想创建一个带有修改过的元数据的新项目集合。 例如,更改ClCompile.AdditionalIncludeDirectories的分隔符。 为此,我首先从AdditionalIncludeDirectories元数据创建一个项集合,然后对其进行转换:
<ItemGroup>
<IncludeDirs0 Include="%(ClCompile.AdditionalIncludeDirectories)">
<key>@(ClCompile)</key>
</IncludeDirs0>
</ItemGroup>
<ItemGroup>
<IncludeDirs Include="@(IncludeDirs0 -> '-I %(Identity)', ' ')">
<key>%(IncludeDirs0.key)</key>
</IncludeDirs>
</ItemGroup>
<ItemGroup>
<Compile Include="@(ClCompile)">
<IncludeDirs>@(IncludeDirs)</IncludeDirs>
</Compile>
</ItemGroup>
问题是如何在Compile项目组上过滤IncludeDirs,这样每个Compile项目的右边都包含dir。 (以便ClCompile标识等于IncludeDirs键)。
我尝试添加条件如:Condition="'%(IncludeDirs.key)'=='%(ClCompile.Identity)'"
但没有任何成功
我本可以直接使用IncludeDirs:<Message Text="%(IncludeDirs.key) : @(IncludeDirs)"/>
但我觉得这一点错过了,因为Compile集合应该包含所有的元数据。
我在这里想念的是什么?
答案 0 :(得分:4)
您可以使用一个额外的目标来收集所需的项目。 请参阅MSBuild Batching。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="1" />
<ClCompile Include="2">
<AdditionalIncludeDirectories>2.1;2.2;2.3</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<Target Name="TransformClCompile"
Inputs="%(ClCompile.Identity)"
Outputs="_Non_Existent_Item_To_Batch_">
<PropertyGroup>
<IncludeDirs>%(ClCompile.AdditionalIncludeDirectories)</IncludeDirs>
</PropertyGroup>
<ItemGroup>
<IncludeDirs Include="$(IncludeDirs)" />
<Compile Include="@(ClCompile)">
<IncludeDirs>@(IncludeDirs ->'-I %(Identity)', ' ')</IncludeDirs>
</Compile>
</ItemGroup>
</Target>
<Target Name="Build" DependsOnTargets="TransformClCompile">
<Message Text="compile %(Compile.Identity) %(Compile.IncludeDirs)" />
</Target>
</Project>
<强>输出:强>
compile 1
compile 2 -I 2.1 -I 2.2 -I 2.3
答案 1 :(得分:3)
使用属性函数可以在4.0+中更简洁地完成它。
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="1" />
<ClCompile Include="2">
<AdditionalIncludeDirectories>2.1;2.2;2.3</AdditionalIncludeDirectories>
</ClCompile>
</ItemGroup>
<Target Name="Build" >
<Message Text="compile %(ClCompile.Identity)" Condition="'%(ClCompile.AdditionalIncludeDirectories)' ==''"/>
<Message Text="compile %(ClCompile.Identity) /I $([System.String]::Join(' /I ', $([System.Text.RegularExpressions.Regex]::Split('%(ClCompile.AdditionalIncludeDirectories)', ';'))))" Condition="'%(ClCompile.AdditionalIncludeDirectories)' !=''"/>
</Target>
</Project>
<强>输出强>
compile 1
compile 2 /I 2.1 /I 2.2 /I 2.3
这不是那么漂亮,但我觉得它好一点。必须使用Regex.Split而不是String.Split,因为后者需要一个分离器数组,这有点棘手。
我认为MSBuild活页夹需要一些改进。
丹(msbuild)