2013-03-28 54 views
5

我在VS2010中为我的VC++项目准备了一个自定义构建规则。在这条规则中,我希望允许用户添加有关文件是否处理的复杂条件。如何在VS2010中暴露MSBuild条件(适用于vC++)

这还需要在目标执行时进行评估,而不是在“项目”本身的“条件”中评估(由于只有“应用程序”项目可以处理它并需要处理它与'应用程序'项目的设置,而不是依赖项目)。

我已经尝试向对象添加一个自定义字段,然后在执行时从组中删除项目。 例如

<ItemGroup> 
    <MyItemType Remove="@(MyItemType)" Condition="!(%(MyItemType.IncludeCondition))" /> 
</ItemGroup> 

不幸的是,这给我的错误:

错误MSB4113: “(%(MyItemType.IncludeCondition))” 规定条件的计算结果为 “ 'testfilename1' == 'testfilename2' 或假的!”而不是布尔值。

(在“%(MyItemType.IncludeCondition)”的原始状态表达'%(Filename)' == 'testfilename2' or $(TestBooleanFalse)

它好像的MSBuild不会对项目的元数据的内容生成一个布尔(这似乎是在很好的做法大多数情况下,只是不是这个)。

有反正我能得到的MSBuild实际评估元下降到一个布尔值,或者是有,我可以用它来得到相同的结果一些其他的方法?


附: 我已经通过的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

尝试编辑职位,但遭到拒绝。请检查它是否你想做的工作http://pastebin.com/nkdz80y5,并考虑包括样本问题 – Lanorkin 2013-04-04 13:30:36

+0

@Lanorkin - 谢谢,你的例子有一个小错误,但它显示了我的问题'有。 (希望人们不会只是回应并说'将'SpecifyConditions'中的'ItemGroup'转换为'Remove',并指定条件为MyItemType声明的条件) – 2013-04-05 02:58:39

回答

0

尝试申报条件直列而不是项目的元数据:

<ItemGroup> 
    <MyItemType Remove="@(MyItemType)" Condition="('%(MyItemType.Filename)' == 'testfilename2')" /> 
    </ItemGroup> 

或者使用Property Functions在元数据中的条件:由内包裹的首要条件

'%(Filename)' == 'testfilename2' or $(TestBooleanFalse) 

('%(Filename)' == 'testfilename2') or $(TestBooleanFalse) 

<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> 
+0

我不能这样做,因为条件是用户为每个文件定义(如原始问题的第二句中所述)。 – 2013-04-01 23:46:29

+0

这是否工作:'Condition =''(%(MyItemType.IncludeCondition))'=='False'“' – KMoraz 2013-04-02 17:11:12

+0

不,想法是'%(MyItemType.IncludeCondition)'扩展为'string'而不是布尔值,尽管它没有被评估 – Lanorkin 2013-04-04 13:47:20

0

我觉得你的条件语句的一个小的调整,从一个支架将解决这个问题。

+0

不,它不会。您可以尝试在这里使用示例http://pastebin.com/nkdz80y5来检查 – Lanorkin 2013-04-04 13:28:25

1

这与MSBuild评估的方式有关。见赛义德的书的详细资料: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> 

+0

在这样的解决方案中,我们仍然使msbuild在'SpecifyConditions'任务中计算条件,而想法是以“通过”条件作为参数,以便它在'Build'任务中计算。 – Lanorkin 2013-04-09 07:40:47