我在VS2010中为我的VC ++项目设置了自定义构建规则。在此规则中,我想允许用户添加关于文件是否被处理的复杂条件。
这也需要在目标执行时进行评估,而不是在“项目”本身的“条件”中进行评估(由于只有“应用程序”项目可以处理它并需要使用它来处理它“应用程序”项目的设置,而不是依赖项目的设置。
我尝试在对象中添加自定义字段,然后在执行时从组中删除项目。 e.g。
<ItemGroup>
<MyItemType Remove="@(MyItemType)" Condition="!(%(MyItemType.IncludeCondition))" />
</ItemGroup>
不幸的是,这给了我错误:
错误MSB4113:指定条件“!(%(MyItemType.IncludeCondition))”评估为“!'testfilename1'=='testfilename2'或false”而不是布尔值。
('%(MyItemType.IncludeCondition)'中的原始条件表达式为'%(Filename)' == 'testfilename2' or $(TestBooleanFalse)
)
似乎MSBuild不会将项元数据的内容评估为布尔值(在大多数情况下这似乎是不错的做法,而不是这个)。
无论如何,我可以让MSbuild实际将元数据评估为布尔值,还是有其他方法可以用来获得相同的结果?
P.S。 我已经对MSBuild Property Functions进行了简要介绍,但是看不到任何会在函数输入上运行MSBuild布尔评估代码的内容。
一个非常精简的MSBuild项目示例,显示了这个问题,由Lanrokin提供:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
<ItemGroup>
<MyItemType Include="item1.ext1" />
<MyItemType Include="item1.ext2" />
</ItemGroup>
<Target Name="SpecifyConditions">
<ItemGroup>
<MyItemType>
<IncludeCondition>'%(Filename)%(Extension)' == 'item1.ext1'</IncludeCondition>
</MyItemType>
</ItemGroup>
</Target>
<Target Name="Build" DependsOnTargets="SpecifyConditions">
<Message Importance="high" Text="@(MyItemType)" Condition="%(MyItemType.IncludeCondition)" />
</Target>
</Project>
答案 0 :(得分:1)
这与MSBuild评估的方式有关。有关详细信息,请参阅Sayed的书:Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build
通过移动样本中条件的位置,您可以完成我认为您想要实现的目标。
<Target Name="SpecifyConditions">
<ItemGroup>
<MyItemType Condition="'%(Filename)%(Extension)' == 'item1.ext1'">
<IncludeCondition>true</IncludeCondition>
</MyItemType>
</ItemGroup>
</Target>
<Target Name="Build" DependsOnTargets="SpecifyConditions">
<Message Importance="high" Text="@(MyItemType)" Condition="%(MyItemType.IncludeCondition) == 'true'" />
</Target>
答案 1 :(得分:0)
尝试声明内联条件而不是项元数据:
<ItemGroup>
<MyItemType Remove="@(MyItemType)" Condition="('%(MyItemType.Filename)' == 'testfilename2')" />
</ItemGroup>
或在元数据条件中使用 Property Functions
:
<Target Name="SpecifyConditions">
<ItemGroup>
<MyItemType>
<IncludeCondition>$([System.String]::Equals('%(Filename)%(Extension)', 'item1.ext1'))</IncludeCondition>
</MyItemType>
</ItemGroup>
</Target>
<Target Name="Build" DependsOnTargets="SpecifyConditions">
<Message Importance="high" Text="@(MyItemType)" Condition="%(MyItemType.IncludeCondition)" />
</Target>
答案 2 :(得分:0)
我认为你的条件陈述的一个小调整来自:
'%(Filename)' == 'testfilename2' or $(TestBooleanFalse)
到
('%(Filename)' == 'testfilename2') or $(TestBooleanFalse)
通过将第一个条件包装在括号内来解决问题。