如何在VS2010中公开MSBuild“条件”(对于vc ++)

时间:2013-03-28 07:26:32

标签: visual-studio-2010 visual-c++ msbuild msbuild-4.0

我在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>

3 个答案:

答案 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)

通过将第一个条件包装在括号内来解决问题。