【问题标题】:Why doesn't MSBuild ItemGroup conditional work in a global scope为什么 MSBuild ItemGroup 条件不能在全局范围内工作
【发布时间】:2010-07-16 14:03:16
【问题描述】:

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

<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 测试项目1 测试项目1 测试项目1

这按预期工作:

<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 测试项目1

但是这个:

<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、元数据和/或全局范围究竟有什么不了解?

【问题讨论】:

    标签: msbuild


    【解决方案1】:

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

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

    【讨论】:

    • 当然,您不能在目标之外使用批处理。我认为这是因为解析器只读取全局范围一次(所以它解析时不知道其中定义了什么=>不可能进行批处理)。至于 ItemGroup 和 CreateItem 之间的区别,您可以阅读这些主题:stackoverflow.com/questions/937681/createitem-vs-itemgroupstackoverflow.com/questions/3891065/…
    • 文档(现在?)说CreateItem is deprecated,所以除非必要,否则我会避免使用它(我认为它比ItemGroup 更积极地扩展参数)因为在遥远的未来,也许它不会包含在.net 中;-)。因此,它可能不是“语法糖”。
    猜你喜欢
    • 2019-01-26
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-12
    • 1970-01-01
    • 2011-09-25
    • 2018-07-27
    相关资源
    最近更新 更多