Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I expose MSBuild 'Conditions' in VS2010 (for vc++)

I've got a custom build rule in VS2010 for my VC++ project. In this rule, I'd like to allow the users to add complex conditions on whether the file is processed.

This also needs to be evaluated at the time of the target execution rather than in the 'Condition' of the 'Item' itself (due to the fact that only the 'application' project can process it and needs to process it with the settings of the 'application' project and not the dependent projects).

I've tried adding a custom field to the object and then just removing the items from the group at execution time. e.g.

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

Unfortunately, this gives me the error:

error MSB4113: Specified condition "!(%(MyItemType.IncludeCondition))" evaluates to "!'testfilename1' == 'testfilename2' or false" instead of a boolean.

(The original condition expression in '%(MyItemType.IncludeCondition)' was '%(Filename)' == 'testfilename2' or $(TestBooleanFalse))

It seems as though MSBuild won't evaluate the contents of the item metadata to a boolean (which seems like good practice in most circumstances, just not this one).

Is there anyway I can get MSbuild to actually evaluate the metadata down to a boolean value, or is there some other method I could use to get the same result?


P.S. I've had a brief look through the MSBuild Property Functions, but couldn't see anything that would run the MSBuild boolean evaluation code over the function input)


A very trimmed down example of an MSBuild project showing the issue, courtesy of 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>
like image 330
Grant Peters Avatar asked Nov 12 '22 08:11

Grant Peters


1 Answers

This has to do with the way in which MSBuild evaluates. See Sayed's book for more information: Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build

By moving the location of the condition in the sample, you can accomplish what I think you were trying to achieve.

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

like image 112
MSBuildPM Avatar answered Nov 15 '22 07:11

MSBuildPM