为什么MSBuild ItemGroup条件不在全局范围内工作

时间:2010-07-16 14:03:17

标签: msbuild

我非常好奇为什么我无法根据在目标内部按预期工作的元数据条件在全局范围内创建项目。例如,这可以按预期工作:

<ItemGroup>
    <TestItems Include="TestItem1">
        <TestFlag>true</TestFlag>
    </TestItems>
    <TestItems Include="TestItem2">
        <TestFlag>false</TestFlag>
    </TestItems>
</ItemGroup>

<Target Name="Default">

    <Message Text="@(TestItems)" />
    <Message Text="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />

    <ItemGroup>
        <FilteredTestItems Include="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />
    </ItemGroup>

    <Message Text="@(FilteredTestItems)" />
    <Message Text="@(FilteredTestItems)" Condition="'%(FilteredTestItems.TestFlag)'=='true'" />

</Target>

并生成以下输出:

TestItem1; TestItem2   TestItem1   TestItem1   TestItem1

这可以按预期工作:

<ItemGroup>
    <TestItems Include="TestItem1">
        <TestFlag>true</TestFlag>
    </TestItems>
    <TestItems Include="TestItem2">
        <TestFlag>false</TestFlag>
    </TestItems>
</ItemGroup>

<ItemGroup>
    <FilteredTestItems Include="@(TestItems)" Condition="'false'=='true'" />
</ItemGroup>

<Target Name="Default">

    <Message Text="@(TestItems)" />
    <Message Text="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />


    <Message Text="@(FilteredTestItems)" />
    <Message Text="@(FilteredTestItems)" Condition="'%(FilteredTestItems.TestFlag)'=='true'" />

</Target>

产生以下输出:

TestItem1; TestItem2   TestItem1

但是这个:

<ItemGroup>
    <TestItems Include="TestItem1">
        <TestFlag>true</TestFlag>
    </TestItems>
    <TestItems Include="TestItem2">
        <TestFlag>false</TestFlag>
    </TestItems>
</ItemGroup>

<ItemGroup>
    <FilteredTestItems Include="@(TestItems)" Condition="'%(TestItems.TestFlag)'=='true'" />
</ItemGroup>

产生以下MSBuild错误:

temp.proj(13,45):错误MSB4090:在条件“'%(TestItems.TestFlag)'=''true'”的位置2处找到意外字符'%'。

那是什么给出的?当然我可以解决它,但究竟我对ItemGroup,元数据和/或全局范围的理解是什么?

1 个答案:

答案 0 :(得分:4)

项目组条件在目标之外工作,但批处理不起作用(即“%”运算符)。当您调用任务时使用批处理,并且由于您只能从目标内部调用任务,因此批处理也只能在目标内部工作。

您可能会问为什么项目组在目标内部工作,因为它不是任务。在MSBuild 3.5之前,根本不允许在目标内部使用项目组;你不得不拨打CreateItem。在版本3.5和4.0中,允许使用这种方式的项目组,但我认为它只是调用CreateItem任务的语法糖,所以你的条件有效,因为幕后的任务